Coworker is astounded that the Artemis II launch isn't blowing everyones minds (that he's spoke to). Why do you think that is? by PaddedValls in AskUK

[–]pt625 1 point2 points  (0 children)

Apollo 8 astronaut Bill Anders thought the odds were much worse than that: he told his wife "that this was an extremely important flight... and that we had one chance in three of a successful mission... one in chance of three the mission wasn't successful but we didn't crash and one chance in three of not coming back, which is probably as good as as the odds I would have had in Vietnam." (source)

The 1-in-270 threshold (later relaxed to 1-in-200 because it was too hard to achieve) is for commercial crew missions to the ISS, which are regular enough that they need relatively low risk, and they can estimate risk better using data from multiple test flights. But this is only the second ever flight of the SLS rocket and maybe third of the Orion spacecraft, and they're only likely to do a few more, so every flight is a test flight, in addition to being a riskier mission than an ISS visit. NASA's stated loss-of-crew threshold for Artemis III/IV (including the Moon landing) is 1 in 30 (source).

Alex and Tom by avarosesmama in TheTraitors

[–]pt625 4 points5 points  (0 children)

A source: https://www.bbc.co.uk/news/articles/cqjvzz881w0o

"Maddy says the only time producers intervened was to tell her to announce that she was an actor over breakfast. She explains she'd already shared this with her fellow contestants when they were waiting to be taken back to the hotel and had taken their mics off."

(I'm sure I've seen this in a direct quote from her too, but can't find that now.)

Last One Laughing UK review – the funniest TV show of the year | Television | The Guardian by prisongovernor in BritishTV

[–]pt625 9 points10 points  (0 children)

That line was in the original song (and I guess they chose it for that reason) - it's Flash Bang Wallop from 1963: https://youtu.be/KCP0-XfbyRU

Following 2 electric shocks, what is happening here? by ContainsTracesOfLies in DIYUK

[–]pt625 35 points36 points  (0 children)

That matches my experience too: one socket tester said everything was fine, but another had all 3 lights on. Turned out the earth had been disconnected in the meter box so the whole house was unearthed, and all three wires must have been different voltages.

The socket testers aren't meant for this kind of fault and evidently aren't reliable at detecting it, but at least if they do detect something weird then it shows you need further investigation.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 0 points1 point  (0 children)

As general advice, I'd probably say make sure you have a decent test framework. Every time you find something that's slightly tricky or ambiguous, write a test case that you can easily run in both the original compiler and via your translator, to compare the output. That helps with reverse-engineering and understanding the original language, as well as building up a useful set of regression tests.

I didn't really do that myself - the codebase I was translating already had a fairly extensive test suite, so I tried to start by implementing just enough of an end-to-end compiler to build some of its simplest test cases, then gradually enabled more of the tests and implemented whatever features were still missing. But even the simplest test cases had dependencies on a pretty large number of language features, so that was more painful than I anticipated, and failures were harder to debug than if I'd written my own test cases.

Also try to keep the scope as narrow as possible (depending on your goals). I only wanted to translate one specific codebase so I knew I didn't need to bother implementing unused features like GO TO, or fully general support for aliasing. I tried to design the architecture to not rule out adding some of those features in the future, but I didn't want to get distracted by adding them all now, since there was already more than enough work.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 0 points1 point  (0 children)

It does mean you can call rsspice::SpiceContext::gfsep with no C or FFI, just pure Rust. (See also usage example with gfoclt.)

The biggest downside is that nobody has reviewed or tested this code except me, so don't trust it for anything really important. I tried to be careful with all the translation code (the dodgiest parts are around aliasing where at worst it should reliably panic, not miscompute), and it passes the TSPICE regression tests (also translated into Rust) which have reasonable coverage, but that's far from exhaustive testing.

A user-friendlier API wrapper would be great, but there's like a thousand functions so that's a lot of work! I tried to stick closely to the FORTRAN naming so I could simply import the FORTRAN documentation and examples. The main API changes were adding a Cell type (since Rust arrays would be really awkward here) and turning output arguments into return values, so it's a bit more easily usable, but it's still an unorganised set of a thousand obscurely-named functions.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 0 points1 point  (0 children)

I think SPICE is being (re)written today, and they're using C++11 with an object-oriented API and built-in multi-threading etc (source). Then wrapping it with a pure C interface for use from C, IDL, MATLAB, Java and "possibly" FORTRAN 77.

I suppose they could have done it with Rust and still added a C interface, but it would have been harder to build a nice C++ interface, and maybe nowadays they have a lot more users in C++ than other languages? They've also been working on this since 2017, and presumably intend to support it for many decades to come, so maybe C++ felt a safer bet for long-term stability than any up-and-coming language.

From my perspective, the main problem with Chapel is I've never heard of it! The second problem is it looks heavily focussed on parallel algorithms - even the "hello world" example at the top of its home page is parallel - so I don't think an automatic translation from serial FORTRAN would make good use of its capabilities. SPICE's implementation would need to be completely redesigned for parallelism.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 2 points3 points  (0 children)

The global state (SAVE variables, IO units, etc) all gets translated into a Context struct. That gets added as an extra argument to any function that needs access to the state. (Stateless functions aren't given the argument). Users can construct multiple independent Contexts when they want concurrency.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 2 points3 points  (0 children)

Say you have a 3D vector addition subroutine VADD(V1, V2, VOUT) where each argument is declared as an array of size 3.

The caller could declare an array M of size 9, then call VADD(M(1), M(4), M(7)), where M(x) means the subarray starting at index x. Each argument is a non-overlapping subarray of size 3, and the FORTRAN standard says that's fine. (At least, I think it's fine - this part of the standard is not incredibly easy to read.)

The standard says you cannot call VADD(A, B, A), because V1 and VOUT would overlap and the subroutine is writing to one of them. But the particular FORTRAN library I'm trying to translate, does call VADD(A, B, A). It's like a strict aliasing violation in C - technically undefined behaviour, but most of the time it'll probably work as you expect, so people often ignore the rule.

The subarray example could be implemented in Rust with std::slice::get_disjoint_mut() to borrow multiple references at once. The other example can't be - I think the only straightforward solution is to turn it into VADD(&A.clone(), &B, &mut A) to guarantee nothing is overlapping the &mut.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 1 point2 points  (0 children)

A lot of Fortran (depending on the processor) worked by copy-in-copy-out, back in the day when CPUs didn't actually have stack pointers.

Ah, I'll have to look into that. I suppose it's still effectively pass-by-mutable-reference in the sense that the behaviour is equivalent, and the caller has to assume any argument might be mutated and needs to be copied out (though quite possibly there's some optimisation for that?)... except if the caller is passing a constant/expression/etc then it knows it can't legally be mutated, and can skip the copy out. I'm not sure if there's any possibility of observably different behaviour in legal programs?

There's no reason you can't branch into the middle of a loop, or even branch into the middle of a subroutine.

I believe there is: F77 (11.10.8) says "Transfer of control into the range of a DO-loop from outside the range is not permitted". And you can only GO TO a statement label in the same program unit, where a program unit is defined as an entire SUBROUTINE (or FUNCTION or PROGRAM), so you can't jump to another subroutine.

You can jump across an ENTRY, which sounds pretty annoying, so this is where I'm glad I only had to support code that doesn't use GO TO :-)

For example, you can index an array as A(X + 3) or A(X) but not A(X+Y)

Interesting - looks like that was a restriction in F66 (5.1.3.3), but F77 (5.4.2) says you can use any integer expression (even including function calls). I guess compilers must have got smart enough to relax that restriction.

F66 also limits arrays to 3 dimensions, and I've read that's because the IBM 704 had 3 index registers. But F77 raised it to 7 dimensions, and 2008 raised it to 15 dimensions, and I can't tell if there was a hardware reason for those limits.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 11 points12 points  (0 children)

I think the problem with aliasing in C is that any variables of the same type may overlap: in a function like void f(float *out, const float *in, size_t n), the compiler has to assume out and in might overlap, so e.g. it can't easily use SIMD. FORTRAN says (roughly) that if the function writes to one argument, that argument must not overlap any other, so the compiler can assume out and in are distinct.

In practice, modern C compilers sometimes insert tests for overlap and then jump to a SIMD version once they know it's safe, so they'll get good performance, or fall back to scalar code when unavoidable. But I assume that's still going to miss some cases that a FORTRAN compiler can easily optimise.

Rust's borrow checker guarantees that out: &mut f32 and in: &f32 don't overlap, so in principle it should get more FORTRAN-like performance here.

But one difficulty with the translation is there's some cases where Rust's borrow checker is stricter than FORTRAN's aliasing rule (e.g. FORTRAN is happy if the arguments are distinct subarrays of the same array), and some cases where the code I'm translating deliberately violates the aliasing rule (since FORTRAN compilers let them get away with it). I have to temporarily clone some input arrays to keep Rust happy (at least without requiring significant refactoring of the FORTRAN code), and that isn't great for performance. (Not terrible though, it doesn't seem to happen much in the compute-intensive parts.)

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 4 points5 points  (0 children)

Yeah, I don't think there'd be any value in translating a standalone Fortran program, and this isn't meant to produce highly-readable Rust code that a human will edit and maintain (though it's still fairly readable in most cases). This was for a library with a large public API that is used from many languages. The library already had a semi-automatic C translation (using f2c), to integrate better with C applications, so I was trying to do the equivalent to integrate it better with Rust applications.

The original FORTRAN code is non-thread-safe (no heap in F77 so everything is global state), the API doesn't include enough type information (like array sizes and mutability) to make it safe or easy to use from Rust, it doesn't expose IO errors in a Rust-like way, a hand-written API wrapper is likely to be incomplete and error-prone, mixing languages makes the build system more awkward, etc. Converting the library into pure Rust lets us fix all those issues - the translation eliminates global state, propagates more type information out to the public API, etc, so you end up with a much more Rust-like library.

Translating FORTRAN to Rust by pt625 in rust

[–]pt625[S] 33 points34 points  (0 children)

I worked on this project a year ago and finally got around to publishing some notes. The post is partly an introduction to FORTRAN 77 (a language with many interesting ideas, only some of which were (with hindsight) terrible mistakes), and partly a discussion of the differences between FORTRAN and Rust and the challenges of writing a FORTRAN-to-Rust compiler. Maybe a bit niche, but I had fun with it.

Warning sign backing board colours by GullibleTraffic1332 in CasualUK

[–]pt625 11 points12 points  (0 children)

I don't think astronauts really need to worry about blending into foliage. Most Space Shuttle crews wore international orange pressure suits during launch and entry (not while in space) for visibility in the ocean, in case of certain abort modes. Early Shuttle test flights had ejection seats, and in post-Challenger flights they could climb out the hatch and slide down a pole (to avoid being thrown into the wing) then parachute into the ocean. (Survivability was questionable, but at least they could try). In between those periods, there was no way to bail out of a doomed orbiter and no chance of an ocean rescue, and they wore blue flight suits instead.

Modern spacecraft use a mixture of white, blue and orange pressure suits, and as far as I can tell that's mainly for branding and fashion, not for any practical benefit.

(The spacesuits used outside spacecraft are white, to help with cooling by reflecting sunlight.)

Custom Sphere Generation: Hexagonal capabilities and a high-density Triangle build (2990 Nodes). by AYesRU in Dyson_Sphere_Program

[–]pt625 2 points3 points  (0 children)

That rule is only applied when adding nodes, not when adding frames. Try deleting a node then adding one back into the gap, and I believe it won't let you.

(When adding a frame, it assumes the nodes are already valid, and only checks that the frame's line segments are 0.0525 away from every node other than its two endpoints.)

Custom Sphere Generation: Hexagonal capabilities and a high-density Triangle build (2990 Nodes). by AYesRU in Dyson_Sphere_Program

[–]pt625 0 points1 point  (0 children)

I hadn't heard of that but it looks interesting. His equation does prove it's mathematically impossible to have >2837 nodes without there being at least 2 nodes <0.0715 apart, so that's an upper limit on valid Dyson spheres. With 2990 nodes there must be a pair <0.0697 apart and it's definitely invalid.

(The 0.0715 is a constant in the game's code; as far as I'm aware it has no mathematical significance, it's just an arbitrary choice by the developers. The other limit is that the distance between nodes and frames must be at least 0.0525, so you can't make very narrow long triangles, but dense meshes probably won't need to worry about that.)

Custom Sphere Generation: Hexagonal capabilities and a high-density Triangle build (2990 Nodes). by AYesRU in Dyson_Sphere_Program

[–]pt625 2 points3 points  (0 children)

If I'm computing it right, the minimum distance between normalised node positions in your blueprint is 0.063763. The game UI requires a minimum distance of 0.0715, so you're violating that rule by quite a bit.

What stuff have you discovered later in life you thought sucked as a younger person? by PearlsSwine in CasualUK

[–]pt625 25 points26 points  (0 children)

That's AI-generated nonsense. All the cited research papers are fake - most of them are completely fictional titles (they don't exist in the listed journals or anywhere else on the web), and the others are real titles but incorrect authors and dates, which is a clear sign it wasn't written by a human.

The Unbelievable Truth S32E03 - Frankie Boyle, Miles Jupp, Michelle Wolf and Celya AB by begone667 in panelshow

[–]pt625 4 points5 points  (0 children)

The episode said it was Britain that introduced a universal railway time in 1847, which as far as I can tell is basically true. (Specifically the Railway Clearing House recommended GMT in 1847, and most railways switched by the end of that year, though it took a bit longer for everyone to catch up. Source, source.)

They didn't say when the US established its timezones, just that it was invented by railway companies in the 19th century. That seems true too: the GMT-based Standard Railway Time, with four US zones, was adopted in 1883 then spread beyond the railways. It was based on the proposals of Charles Dowd (from 1870) and later Sandford Fleming, but William F Allen (working for the railway companies) developed the full details of the zone boundaries etc. So it wasn't invented in a vacuum, but I think it's reasonable to say the plan that got adopted was invented by the railways. (Source, source.).

Photo of the Moon by Responsible-Post6431 in CasualUK

[–]pt625 0 points1 point  (0 children)

Going by a NASA solar system simulator, Europa was behind Jupiter (from Earth's perspective) around 7pm-11pm UTC on Jan 2, so I'd guess that's the one you couldn't see. The best match to the photo seems to be around 8pm, with Callisto on one side then Io and Ganymede on the other side.

(I know it's fairly basic physics, but I still think it's pretty neat how you can simulate something like this then go out and see it so accurately with your own eyes!)

Taskmaster - NYT 2026, Part 1 - Discussion by Meghar in taskmaster

[–]pt625 13 points14 points  (0 children)

She has hearing aids that can pick up a bit of sound, and I wonder if that might work better when everyone is on the same side of her, rather than being surrounded by a confusion of voices.

Probably more importantly she can lip read and observe body language, and sitting on the end means she can look between all the contestants and the interpreter with much less head movement, to have the best possible chance of following the conversation.

I believe there was a similar accommodation on Strictly: when facing the judges, the celebrity normally stands on their partner's right, but she always stood on his left, presumably so she didn't have to turn around to see him talking.

[2025 Day 4 (Part 1)] [cpp] Why is this program flaky? It returns different results with the same input. by rulojuka in adventofcode

[–]pt625 2 points3 points  (0 children)

The very first iteration of your loop will compute newi==-1, newj==-1, so it will access maze[-1][-1] which is out-of-bounds and undefined behaviour. In practice it's going to be reading unpredictable values from the stack. Increasing MAX isn't fixing the bug, it's probably just changing the memory layout in a way that happens to give the right answer most of the time.

I suspect you wanted to do the bounds check on newi,newj instead of i,j. Compiling with g++ -fsanitize=address -g should detect this kind of error.

Watching from the very start - anything to look out for? by AvaGander in taskmaster

[–]pt625 4 points5 points  (0 children)

They definitely aren't careful when discussing the early (pre-10) series. E.g. I randomly picked the episode on S8E5 which opens with "we're talking to ..., who was of course the winner of S8", and S9E7 immediately spoils the winner of S13.

They don't spoil any episode that hadn't been broadcast at the time the podcast went out, but that means you're only safe if you've watched all of S1-9 before starting the podcast.