#BabelOfCode 2024
Week 4
Language: FORTRAN
Confidence level: High
PREV WEEK: mastodon.social/@mcc/113867584…
NEXT WEEK: mastodon.social/@mcc/113975448…
RULES: mastodon.social/@mcc/113676228…
I was very excited about doing TCL this week, but I told myself the first time I get a two-dimensional array problem I'd go FORTRAN, so I guess this week is FORTRAN.
A friend of mine who did AOC2024 in December noted the early challenges this year were *very* easy. Today's definitely is. I wonder if part 2 will have any depth.
Questa voce è stata modificata (8 mesi fa)
Giuseppe Aceto reshared this.
mcc
in reply to mcc • • •I went into this thinking: C is basically cleaned up FORTRAN, right? I know C? This should be easy, right? Right off the bat I find there will be a lot of difficulties entirely not of the kind I'm used to in programming. After a brief adventure with accidentally naming my file .f and not .f90 causing horrific and baffling errors, I run a hello world off the Internet. There's a space before the printout. Hm, how do I turn that off?
stackoverflow.com/a/31236043
Oh my fuck, *what*?
How to get rid of unwanted spacing in Fortran's print output?
Stack Overflowmcc
in reply to mcc • • •I get frustrated with C all the time for being fundamentally a 70s language. It may be I'm about to learn the pain of using a *50s language*.
(Alternately, I hear modern FORTRAN has all kinds of fancy niceties like operator overloading and might not resemble traditional FORTRAN all that much. But then I have the problem if I pick up a random tutorial it's hard to guess which *decade's* standard it's teaching me from, or if it's the GNU extension, if the GNU extension is that different, etc.)
Oblomov reshared this.
Veronica Olsen 🏳️🌈🇳🇴🌻
in reply to mcc • • •mcc
in reply to Veronica Olsen 🏳️🌈🇳🇴🌻 • • •@veronica Where would you recommend starting to ensure I'm learning FORTRAN 2003 or FORTRAN 2023 and not something ancient and unnecessarily inconvenient?
Does anyone use GNU FORTRAN (ie, asking if they use -std=gnu, not asking if they use gfortran) in industry?
Veronica Olsen 🏳️🌈🇳🇴🌻
in reply to mcc • • •We supported GNU, Intel and the Nagfor compilers. Honestly, my best resource was the Intel Fortran forums, which are not public. I had a university Intel account though.
I also have a draft copy of one of the Fortran standards that I used for reference. It is quite tricky to find good resources online unfortunately.
pancomputans
in reply to mcc • • •mcc
in reply to mcc • • •Just learned FORTRAN has an aint() function
Don't that just beat all
Oblomov reshared this.
Gary
in reply to mcc • • •Foone🏳️⚧️
in reply to mcc • • •mcc reshared this.
mcc
in reply to Foone🏳️⚧️ • • •@foone pretty sure no
I assume that the "y'all" keyword would be a standin for every variable in scope. So you say
y'all += 4
and it adds 4 to all variables.
It might be possible to implement this in userspace in Python.
reshared this
mcc e Oblomov reshared this.
Hugo "Dark Satanic" Mills
in reply to mcc • • •mcc
in reply to Hugo "Dark Satanic" Mills • • •all y'all — increments all globals and locals
Andrew
in reply to mcc • • •xinit ☕
in reply to mcc • • •caracabe but spooky
in reply to mcc • • •plinth
in reply to mcc • • •✧✦Catherine✦✧
in reply to mcc • • •✧✦Catherine✦✧
in reply to ✧✦Catherine✦✧ • • •reshared this
Oblomov reshared this.
xinit ☕
in reply to mcc • • •T. J. Bombadil
in reply to mcc • • •Ken Butler has moved
in reply to mcc • • •mcc
in reply to mcc • • •LibertyBeta
in reply to mcc • • •mcc
in reply to mcc • • •Here is my current program. At the moment, all it does is take a command line argument (a path) and attempt to open the specified file. I build it with `gfortran src/puzzle.f90 -std=f2023 -o program`
github.com/mcclure/aoc2024/blo…
I'm having two problems, one serious, one unserious.
The unserious problem: I want to abort if the # of arguments is bad. If I do "error stop", it prints a backtrace, which I didn't ask for. If I do "call abort", gfortran fails to link ("undefined reference to 'abort_').
aoc2024/04-01-wordsearch/src/puzzle.f90 at 822e460f81b944c21ca675303b868c45b22a4c2b · mcclure/aoc2024
GitHubmcc
in reply to mcc • • •Here's my serious FORTRAN problem (code link in previous post):
The recommended GET_COMMAND_ARGUMENT function seems to assume you know the length of the argument ahead of time. Obviously, I don't.
gcc.gnu.org/onlinedocs/gfortra…
It allows me to pass in an `allocatable` string, but I believe it is leaving that string of length 0 if I do not ALLOCATE() it, and the fetched string is ''. Is there a way to get the length of a command-line argument before GET-ing it?
I see GET_COMMAND, but that's… awkward
GET_COMMAND_ARGUMENT (The GNU Fortran Compiler)
gcc.gnu.orgSpo0000opybirb
in reply to mcc • • •mcc
in reply to Spo0000opybirb • • •Spo0000opybirb
in reply to mcc • • •holy gods there's a 2023
I would hope so, but since I don't know it, I'm handing you an older-FORTRAN best practice you can use if you can't a better method.
Veronica Olsen 🏳️🌈🇳🇴🌻
in reply to mcc • • •I rarely use this, but the way I've done it in the past is to allocate the argv character to a sensible buffer size, initialise it to " ", and use trim() on it when using it, which will strip the unused part of the buffer.
Example:
character(len=4096) :: arg
arg = " "
call get_command_argument(1, arg)
call my_code(trim(arg))
Ken Milmore
in reply to mcc • • •mcc
in reply to Ken Milmore • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •mcc
in reply to mcc • • •…hm. I am concerned.
According to the FORTRAN working group
wg5-fortran.org/N2201-N2250/N2…
As of the 2023 standard, an un-allocated deferred-length variable may have its length set by calling intrinsic procedures; they give GET_COMMAND as an example specifically, and StackOverflow users assert GET_COMMAND_ARGUMENT is also included.
I don't get this behavior. My argument is being input as ''.
Do you think this means my code (linked above) is wrong, or that gfortran -std=f2023 is nonconformant?
Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •how do you mean ". ? the shell won't let you enter it.
You'd have to quote it as '".' Using the example proggy from the manual for GET_COMMAND_ARGUMENT gives you then
$ ./a.out 333 '".'
./a.out
333
".
mcc
in reply to Dima Pasechnik 🇺🇦 🇳🇱 • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •mcc
in reply to Dima Pasechnik 🇺🇦 🇳🇱 • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •in old fortrans an empty string still had length 1.
Something like
CHARACTER FOO
[1]can hold a zero-length string.
Fortran 77;
----
There are no null (zero-length) character-string variables. A one-byte character string assigned a null constant has the length zero.
---
I'd be surprised if this has changed.
mcc
in reply to mcc • • •Oh my hell lol, I sincerely believe I have found a bug (standard nonconformance) in GNU FORTRAN 14.2.0 and I have a repro case
github.com/mcclure/aoc2024/blo…
Am I going to have to figure out how to report a bug on GNU. Geez. Is this going to be like the bureaucracy planet scene in Jupiter Rising
aoc2024/04-01-wordsearch/src/puzzle.f90 at b31be91adb5a0721f97e2ba8f145da4f36129753 · mcclure/aoc2024
GitHubPunnO)))
in reply to mcc • • •mcc
in reply to PunnO))) • • •PunnO)))
in reply to mcc • • •mcc
in reply to mcc • • •Now that I have successfully figured out how to read an argument from the command line without knowing its length ahead of time, I am stuck on figuring out how to read a line of text from a file without knowing its length ahead of time. Apparently not an expected FORTRAN use case. I think the trick I was using before will not work, or at least, I *think*
read(10,"(a)",size=line_length,advance='NO') line_in
should read a line without advancing the filehandle and save the size. But it saves 0.
mcc
in reply to mcc • • •Jon Dubovsky
in reply to mcc • • •mcc
in reply to mcc • • •Incidentally, I am very comfortable usually with reading language specifications, but I got hold of a copy of the FORTRAN 2008 spec and… this is one of the least friendly language specifications I've ever seen, when reading it to try to determine how a program should be written.
(Trivia: When the image on the right says something like "the value must be YES or NO" what they mean is "the value must be 'YES' or 'NO'.)
Oblomov reshared this.
Spo0000opybirb
in reply to mcc • • •Aw yeah as someone with extensive experience in Old FORTRANs it's always been like that.
Just be glad they stopped the slash-through-the-letter-O thing. It's so unimportant and yet so annoying, since everyone else who used a slashthrough used it for zero. And that includes Amateur Radio, so I don't know _what_ FORTRAN was thinking.
Efexor Zolpidem
in reply to Spo0000opybirb • • •mcc
in reply to Efexor Zolpidem • • •Spo0000opybirb
in reply to mcc • • •itym JØHN
sfairesphobic bastard
Mark T. Tomczak
in reply to mcc • • •Rob
in reply to mcc • • •mcc
in reply to mcc • • •FORTRAN 2008 spec 9.1:
"A file is composed of either a sequence of file storage units (9.3.5) or a sequence of records… A file composed of file storage
13 units is called a stream file."
The definition of "file storage units" (9.3.5):
"A file storage unit is the basic unit of storage in a stream file or an unformatted record file."
The linked definition of "Stream file" (1.3.139)
A file composed of a sequence of le storage units (9.1)
YOU ASSHOLES, THIS DEFINITION IS CIRCULAR!
mcc
in reply to mcc • • •Cassandra is only carbon now
in reply to mcc • • •mcc
in reply to mcc • • •git discovery: you cannot check a file you do not have permissions to into a repository.
problem: my repo contains a directory of test files. this directory contains a second directory of "invalid" tests, i.e., tests that the program is *expected* to fail on (and if it doesn't fail cleanly that's an error). one of the "invalid" tests is a file the program doesn't have read permissions to.
I cannot check my "file with no read permissions" test case into the repository 🙁
Oblomov reshared this.
✧✦Catherine✦✧
in reply to mcc • • •mcc
in reply to ✧✦Catherine✦✧ • • •jcoglan
in reply to mcc • • •mcc
in reply to jcoglan • • •Genders: ♾️, 🟪⬛🟩; Soni L.
in reply to mcc • • •we'd ship a (small) filesystem image.
not sure what to do about windows...
GeePawHill
in reply to mcc • • •a) drag, and b) nice negative test case!, and c) I have a folder "testing" in my repo that is .gitignored. I'd programattically touch the file and then change it's permissions and then test against that.
I was just musing about a similar problem: I need some tests that my code manipulates a git repo successfully. Can't put .git folders in a subfolder, git shits its pants.
mastodon.social/@GeePawHill/11…
GeePawHill (@GeePawHill@mastodon.social)
Mastodonmcc
in reply to mcc • • •Since automatic deferred length initialization is not working as the spec seems to require, I decided to just read the file in line by line.
This was much harder than I expected! The GNU docs do not well describe READ/WRITE, but do well describe the standard library functions. So I wrote around FGETC(), but then it turned out this is a GNU extension (or possibly was in FORTRAN 77 but not future FORTRANS?) so I had to rewrite to use normal READ in "Stream mode"… not in the GNU docs * _ *
(1/2)
mcc
in reply to mcc • • •I wound up slowly picking my way through the 2008 language spec, as previously mentioned not super readable. But I got it to work:
github.com/mcclure/aoc2024/blo…
Annoyed I had to spend all this time just doing file management, I decided to do the file management REALLY WELL. It's got unique error messages for different types of file handling errors and everything!
Now if only I could make gfortran suppress that darn `error stop` backtrace..
(2/2)
aoc2024/04-01-wordsearch/src/puzzle.f90 at a8835dcd8ad0162268ef16708f9a7cd8b6d45958 · mcclure/aoc2024
GitHubmcc
in reply to mcc • • •Oblomov reshared this.
mcc
in reply to mcc • • •A reply I got on a previous post in this thread suggested that the reason the FORTRAN spec is so strict about using the word "file storage unit" instead of the normal terminology "byte" is that FORTRAN is from 1957 and literally predates the world at large adopting the vocabulary "byte" for the minimum addressable storage in a filesystem. Well, geez. That might really be it.
(Also note FORTRAN's commitment to line numbers is so great that even the English text of the spec has line numbers.)
Oblomov reshared this.
Cassandra is only carbon now
in reply to mcc • • •mcc
in reply to Cassandra is only carbon now • • •Cassandra is only carbon now
in reply to mcc • • •mcc
in reply to Cassandra is only carbon now • • •Cassandra is only carbon now
in reply to mcc • • •mcc
in reply to Cassandra is only carbon now • • •Cassandra is only carbon now
in reply to mcc • • •mcc
in reply to Cassandra is only carbon now • • •Cassandra is only carbon now
in reply to mcc • • •Carl Muckenhoupt
in reply to mcc • • •Mark T. Tomczak
in reply to Cassandra is only carbon now • • •@xgranade One of those wild bits of trivia about C++ is that there are parts of the spec that don't assume a byte is 8 bits, because it's old enough to have cared about targets where that isn't true.
I want to say it's around C++, like, 20? Where they introduced some modifiers on string literals to let you be explicit about the encoding, because otherwise encoding is an implementation detail and that means your strings might get jammed into 7-bit representations on some compilation targets.
mcc
in reply to Mark T. Tomczak • • •broonie
in reply to mcc • • •dani little ponie
in reply to mcc • • •apparently the term "byte" was coined in 1956, so. yeah that's entirely plausible
on the other hand you are reading the specification for fortran 2008, which was approved in 2010, not the original fortran specification drafted in 1954
we knew what bytes are in 2008
reshared this
mcc e Oblomov reshared this.
mcc
in reply to dani little ponie • • •mcc reshared this.
Ted Mielczarek
in reply to mcc • • •Leon
in reply to mcc • • •mcc
in reply to Leon • • •Mark T. Tomczak
in reply to mcc • • •I wonder if that's a FORTRAN thing or an IBM thing? It's been an age since I read Mythical Man Month, but I remember Fred Brooks mentioning one of the innovations at IBM was to keep documentation in binders so that individual pages could be hot-swapped as errata were published. I mean, nowadays we use word processors and cloud collaboration tools, but I'm sure that was hot shit back in the '70s.
I bet line numbers would have made it a lot easier to publish errata that said stuff like "Lines 305-335 on page 69 are OBSOLETE. Replace with the following:"
mcc
in reply to mcc • • •Oblomov reshared this.
dani little ponie
in reply to mcc • • •Chris Hanson
in reply to mcc • • •Sensitive content
mcc reshared this.
mcc
in reply to Chris Hanson • • •Joe Groff
in reply to mcc • • •Chris Hanson
in reply to mcc • • •Sensitive content
VMS Monster
web.archive.orgreshared this
mcc e Oblomov reshared this.
mcc
in reply to Chris Hanson • • •mcc
in reply to mcc • • •So the reason I picked this puzzle for FORTRAN was I heard FORTRAN's builtin multidimensional array types were nice. I probably won't be truly making deep use of those in the end, but I'm at least learning one thing from the experience: FORTRAN's builtins are *not* especially nice for *growable* arrays, regardless of dimension. You can *do* it, but it's not efficient or super friendly. I realized my growable implementation would be O(n^2) on file size, just to read the file into memory.
(1/2)
mcc
in reply to mcc • • •Fortunately, I can make everything easy again by just scanning the file to determine the size of the multidimensional array I need to allocate, seeking back to the beginning, then actually reading the array in. It probably sounds to you like I just made a very basic statement. But something to make clear: fseek() is actually considered a very advanced feature in FORTRAN, and was only added to the language in 2003 (in other words 46 years after the language was first specified)
(2/2)
Oblomov reshared this.
Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •mcc
in reply to Dima Pasechnik 🇺🇦 🇳🇱 • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •Surely, multitasking OSs are later invention than Fortran. In the olden days you just allocated (statically) however much RAM you could, and use it as you please. If your data won't fit into RAM, then it's a different, much harder, issue...
Rivimea, god of accidents
in reply to mcc • • •mcc
in reply to Rivimea, god of accidents • • •@sklrmths What they came up with is not terrible. I'm not even willing to say it's worse than what we have in C.
Like, it would be *nice* to have realloc, but I've never felt *really* convinced that realloc in C actually works
mcc
in reply to mcc • • •mcc
in reply to mcc • • •reshared this
azul e Oblomov reshared this.
Howard Chu @ Symas
in reply to mcc • • •mcc
in reply to Howard Chu @ Symas • • •Howard Chu @ Symas
in reply to mcc • • •mcc
in reply to Howard Chu @ Symas • • •mcc
in reply to mcc • • •Oblomov reshared this.
Michael Cook
in reply to mcc • • •mcc
in reply to mcc • • •OK so
I am using the stream input mode for my file input (this freaks the fuck out of every FORTRAN programmer on this site, but)
I need to seek to the beginning of the file. A stack overflow comment suggests this is done with
read(10, "()", advance='no', pos=1)
gfortran prints
runtime error: Format present for UNFORMATTED data transfer
I remove the "()"
read(10, advance='no', pos=1)
Compiler balks
Error: the ADVANCE= specifier at (1) must appear with an explicit format expression
WDID
mcc
in reply to mcc • • •Oblomov reshared this.
mcc
in reply to mcc • • •My fuzzy read of the standard is that the "()" version above is probably inaccurate, but the version without the "()" should probably in this case compile.
I'm actually kinda stuck here, and this (the ability to seek within a file) is a banner feature of the post-2000 STREAM mode, so I think: I wonder if there's a Discord, IRC, otherwise realtime communication channel for FORTRAN programming I could tap.
fortranwiki.org/fortran/show/I…
*squeaking* "No… no!!!"
IRC in Fortran Wiki
fortranwiki.orgmcc
in reply to mcc • • •Oblomov reshared this.
mcc
in reply to mcc • • •I successfully worked around gfortran's apparent refusal to do a nonadvancing read by having my actual read look like
if (row_at == 1 .and. col_at == 1) then
! If we detect this is the first character of the file, reposition
read(10, iostat=file_error, pos=1) char_in
else
read(10, iostat=file_error) char_in
end if
But I really, really, *really* hate it
TTimo
in reply to mcc • • •mcc
in reply to mcc • • •I am experiencing confusion about apparent disjoint between docs and behavior. Is the following correct?
! This allocates a matrix "board" of COLS columns and ROWS rows
allocate(board (cols, rows))
! This writes to the "bottom right" cell of board
board(rows, cols) = 1
Everyone agrees FORTRAN is column-major in memory but get vague about syntax (lots of examples where indices are named "i" and "j"). I get incorrect behavior if I DON'T swap rows,cols order between allocation and write/read.
Oblomov reshared this.
Tachibana Kanade
in reply to mcc • • •mcc
in reply to mcc • • •mcc
in reply to mcc • • •*rubbing eyes*
So I am reading this tutorial
masuday.github.io/fortran_tuto…
I write a program with a helper subroutine using CONTAINS. It's fine. Now I want a helper function. gfortran says "unclassifiable statement" on the word "function". I try literally copypasting the sample code from the tutorial. gfortran rejects the sample code, again saying `function` is "unclassifiable", in all of f2023, f95, and GNU.
What the devil?
Haven't tried digging into the spec (which is made of hell) yet.
Function and subroutine
masuday.github.iomcc
in reply to mcc • • •All right.
Part 1: github.com/mcclure/aoc2024/blo…
Part 2: github.com/mcclure/aoc2024/blo…
Did I learn anything from this? I guess. Yeah. Okay, I guess so.
That wasn't particularly unpleasant. The ergonomics weren't great, but were not-great in forgivable ways. The fact each tutorial/doc/StackOverflow answer I found targeted a different FORTRAN std was definitely frustrating. I got to add an array to an array on two (2) lines of part 2, and other than that this was basically funny-shaped C. C with paperwork
aoc2024/04-01-wordsearch/src/puzzle.f90 at ca77f141f33ab494dc1bb43f3d6f13e775a36303 · mcclure/aoc2024
GitHubmcc
in reply to mcc • • •The v.a.s.t. bulk of the time here (and in the simpler part 2, the bulk of the code) was spent on file I/O. In the 4 weeks of this project so far, I skipped file i/o (instead embedding the data in the program) for BASIC and ASM, since those are languages with Limitations, and for Forth and FORTRAN I assumed those were Fully Featured so I could just do file i/o. But no, on both Forth and FORTRAN simple file i/o was *a nightmare*, the bulk of the work.
(1/2)
Oblomov reshared this.
mcc
in reply to mcc • • •There's an awkward irony here.
For the Forth week, the input was a list of ASCII numbers. *This* kind of input FORTRAN had easy-to-use builtins for, but Forth had nothing and I had to build it myself.
FORTRAN week, the input was a grid of ASCII characters. *This* Forth could have handled pretty easy, but FORTRAN it's actually sorta impossible unless you use a modern (and, apparently, not completely tested in gfortran??) "stream" mode, which took forever and required consulting the spec. (2/2)
Oblomov reshared this.
mcc
in reply to mcc • • •I got a lot of good help this week (FORTRAN) so, thank you everyone.
I guess that's one "month" of the project down. Here's my completion status.
(Note there are 43 languages on this list, and 25 puzzles in AOC, so only a little over half will get hit by the end. My "for certain" list is: TCL, Haskell, Idris, Smalltalk, Self, Ada, Factor, Mirth, Uiua, at least one of ARM and RISCV.)
Oblomov reshared this.
Paul Will Gamble 🇨🇦
in reply to mcc • • •mcc
in reply to Paul Will Gamble 🇨🇦 • • •@paulywill mastodon.social/@mcc/113676228…
mcc
2024-12-18 22:39:45
Joe
in reply to mcc • • •mcc
in reply to Joe • • •Joe
in reply to mcc • • •mcc
in reply to Joe • • •king toot uncommon
in reply to mcc • • •mcc
in reply to king toot uncommon • • •king toot uncommon
in reply to mcc • • •the tutorial on tcl.tk and the O'Reilly book are how I learned
oreilly.com/library/view/tcltk…
Tcl/Tk in a Nutshell
O’Reilly Online LearningMeg
in reply to mcc • • •mcc
in reply to Meg • • •Elias Mårtenson
in reply to Meg • • •@megmac I'm looking forward to COBOL. Mainly because I've been playing around with it recently.
It's remarkably not terrible in some ways (and very annoying in others). In fact, the aplit between nice and horrible appears to be exactly opposite that of FORTRAN.
mcc
in reply to Elias Mårtenson • • •Ingvar
in reply to mcc • • •Finn
in reply to mcc • • •mcc
in reply to Finn • • •mauvedeity
in reply to mcc • • •Meg
in reply to mcc • • •mcc
in reply to Meg • • •mcc
in reply to mcc • • •I'm not doing the Babel-of-Code challenge this week but Andrzej has his writeup of his Prolog week up
mastodon.gamedev.place/@unjell…
and has started a thread for his week with Lean:
mastodon.social/@unjello@masto…
Andrzej Lichnerowicz (@unjello@mastodon.gamedev.place)
Gamedev MastodonOblomov reshared this.
J3RN
in reply to mcc • • •Tachibana Kanade
in reply to mcc • • •Request Slack Access to the RSE Space
Google Docsmcc
in reply to Tachibana Kanade • • •@h0m54r Heh, neat.
Given this still requires a roundtrip before I can post a question, I might just go ahead and finish this with workarounds and then email the GNU mailing list.
Tachibana Kanade
in reply to mcc • • •NoIQ
in reply to mcc • • •jhamby
in reply to mcc • • •Did you try:
read(10, pos=1)
That's what the example code for stream I/O seems to use.
mcc
in reply to jhamby • • •mcc
in reply to mcc • • •@jhamby this is how i did it
mastodon.social/@mcc/113924441…
mcc
2025-01-31 18:43:34
jhamby
in reply to mcc • • •lambdageek
in reply to mcc • • •mcc
in reply to lambdageek • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •they really butchered things in newer fortran manuals. 😠
in good old days one used CONTINUE to place end of loop labels (or for other similar purposes)
DO 42 J=...
...
42 CONTINUE
as old manuals tell you:
docs.oracle.com/cd/E19957-01/8…
CONTINUE (FORTRAN 77 Language Reference)
docs.oracle.comvivi 💫
in reply to mcc • • •mcc
in reply to vivi 💫 • • •Lucas Treffenstädt
in reply to mcc • • •ideaPDish
in reply to mcc • • •I’ll never forget my first.
Richard Hendricks
in reply to mcc • • •Psentee
in reply to mcc • • •Elias Mårtenson
in reply to mcc • • •Fortran is good for high performance multidimensional array work. But for easy multidimensional work you might want to look into array languages.
But then again, one had a lot of fun reading this thread, so going with Fortran was clearly the right choice. 😃
mcc
in reply to Elias Mårtenson • • •@loke Among the problems here are
1. I don't know what puzzles might be coming later in the set; if I see a non-numerical multidimensional array program and so hold off on FORTRAN because maybe there'll be a good numerical problem later, well, maybe there actually *won't* be.
2. I don't ever know what part 2 will be when I start part 1;
3. I don't truly know what the different languages are good at until I've used them! And that, more than anything else, is the point.
Elias Mårtenson
in reply to mcc • • •definitely. And you documenting it here provided not just entertainment but also valuable information for those of us who might want to go down a similar path in the future. I'm certainly open to using Fortran for solving some problem where its strenghts are useful. But since I've never actually used it beyond simple hello world style programs, these kinds of threads are useful. And not to mention, fun.
I solved 2024 in my own programming language which happens to be an array language, so seeing the Fortran approach was educational.
mcc
in reply to Elias Mårtenson • • •Ted Mielczarek
in reply to mcc • • •reshared this
mcc e Oblomov reshared this.
Ted Mielczarek
in reply to Ted Mielczarek • • •Oblomov reshared this.
mcc
in reply to Ted Mielczarek • • •mcc
in reply to mcc • • •arclight
in reply to mcc • • •@tedmielczarek Until F90, Fortran output sent to a printer or the console was assumed to have an ASA carriage control character as the first character of the line - see en.m.wikipedia.org/wiki/ASA_ca…
The carriage control character would be consumed on output which meant if you started writing output without a leading space (or 0, 1, or +), the first character would get trimmed off. That's why output lines in F77 and earlier start with an extra space - it's a control code for a long obsolete printer formatting scheme.
To get proper formatting of legacy FORTRAN output, POSIX included the `asa` utility: man7.org/linux//man-pages/man1…
Back in the day I made friends with the head of Design Engineering at the power plant where I worked because I knew the obscure magic to make his department's code output legible and not look like total ass. I didn't have much interaction with him otherwise but I was always happy to help him sort out his code output. Good guy.
for computer line printers
Contributors to Wikimedia projects (Wikimedia Foundation, Inc.)mcc
in reply to arclight • • •Ted Mielczarek
in reply to arclight • • •mcc
in reply to Ted Mielczarek • • •Ted Mielczarek
in reply to mcc • • •Ted Mielczarek
in reply to mcc • • •Oblomov reshared this.
Erin
in reply to mcc • • •@tedmielczarek I had to do a lot of parsing of Fortran 77 for my first aerospace internship and was desperately trying to remember what the significance of column 6 was
docs.oracle.com/cd/E19957-01/8…
oh right,
"The first five columns must be blank or contain a numeric label.
Continuation lines are identified by a nonblank, nonzero in column 6."
Source Line Formats (FORTRAN 77 Language Reference)
docs.oracle.comWilliam
in reply to mcc • • •bytes were a thing at that point, but machine architectures were not standardized on multiples of 8 bits.
Plenty of very weird systems with non-standard word lengths and storage record sizes that Fortran would have been intending to support.
argv minus one
in reply to mcc • • •mathew
in reply to mcc • • •Peter McMahan
in reply to mcc • • •reshared this
Oblomov reshared this.
mcc
in reply to Peter McMahan • • •mcc reshared this.
Ludwig Vielfrass
in reply to mcc • • •@peter_mcmahan but:
SHOULD he think like an RFC author?
or
MUST he think like an RFC author?
mcc reshared this.
yuubi
in reply to mcc • • •the rfcs i've used that didn't come from 3gpp-adjacent lands seem to call bytes bytes, and byte means 8 bits unless it's April 1 and time to define utf-9 for compatibility with 36-bit machines that have variable byte sizes
James Henstridge
in reply to mcc • • •Isn't there similar stuff in the C standard w.r.t. CHAR_BIT?
I suppose it is a little more constrained, since they require CHAR_BIT >= 8.
mcc
in reply to James Henstridge • • •James Henstridge
in reply to mcc • • •P3477R2: There are exactly 8 bits in a byte
www.open-std.orgDavid JONES
in reply to mcc • • •jhamby
in reply to mcc • • •Elias Mårtenson
in reply to mcc • • •Joe
in reply to mcc • • •mcc
in reply to Joe • • •Tóth Gábor Baltazár
in reply to mcc • • •afaik git doesn't store permissions or even modification dates
it only stores wether the file is executable or not
Misty
in reply to mcc • • •Julia Evans
in reply to mcc • • •mcc
in reply to Julia Evans • • •@b0rk *thinks*
i may or may not understand what you're proposing. however someone elsewhere in the thread said that the git on-disk format only represents one "readable?" bit per object (IE, it flattens the three-user-category UNIX permissions model to one category), so if that's true it might be there's not actually a way in the format to do the thing you just said.
Andy Price
in reply to mcc • • •github.com/git/git/blob/master…
git/Documentation/gitformat-index.txt at master · git/git
GitHubEllie
in reply to mcc • • •mcc
in reply to Ellie • • •tef
in reply to Julia Evans • • •@b0rk likely nothing good, git only really supports 755 and 644 as modes
github.com/git/git/blob/master…
git/object.h at master · git/git
GitHubJulia Evans
in reply to tef • • •@tef yeah I'm sure it's nothing good, I'm just curious about how exactly it would fail
(technically tree objects are text files and you can put "0400" as the permission, it's just not a valid value)
this is the format:
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 empty.txt
mcc
in reply to Julia Evans • • •Julia Evans
in reply to mcc • • •@tef I tried and it seems very hard to get git to do this, it'll just change the permissions to 644 (which is probably for the best)
gist.github.com/jvns/4d27efda9…
make-commit.sh
GistGretyl
in reply to mcc • • •mcc
in reply to Gretyl • • •@gretyl thank you for suggestion but
mastodon.social/@mcc/113920886…
mcc
2025-01-31 03:39:36
Gretyl
in reply to mcc • • •Ben Zanin
in reply to mcc • • •I'm a little late to this thread and I see you've already both solved your issue and received all the usual advice about making your test scripts initialize the file permissions they require, but I don't think I saw anyone mention this slightly more esoteric solution:
github.com/git/git/blob/master…
Git has included since 2006 a contributed post-checkout/post-merge hook script to apply extended permission & user/group ownership settings stored in a .gitmeta file in the repo root. Rarely useful!
git/contrib/hooks/setgitperms.perl at master · git/git
GitHubschrotthaufen
in reply to mcc • • •Someone found a way to run scripts after git clone. github.com/git-hook/post-clone
Tested with the non curl | bash method, and this in my_repo/hooks/post-clone paste.xinu.at/PymqFy/
GitHub - git-hook/post-clone: Implementation of a git post-clone hook
GitHubMark Eichin
in reply to mcc • • •Fish Id Wardrobe
in reply to mcc • • •Howard Chu @ Symas
in reply to mcc • • •if you used IBM mainframes, this would all be common knowledge. Mainframes don't typically support simple byte-stream files like Unix does. All mainframe files are structured, record-formatted.
And FORTRAN was born in mainframes, so its file handling reflects that. Usually you read input by telling your program which punchcard device to read.
tTh
in reply to mcc • • •Danilo Piazzalunga
in reply to mcc • • •Sensitive content
Sylvhem
in reply to mcc • • •mcc
in reply to Sylvhem • • •Sylvhem
in reply to mcc • • •I should go to bed instead of reading about FORTRAN :').
arclight
in reply to mcc • • •If you are trying to manually control seek and advance with Fortran I/O, you are going to have a very bad day. Fortran I/O is record-oriented and handles a lot of EOL detection and parsing for you. You should not be implementing fprintf() because write() and format() will do basically everything you need.
character(len=32) :: mystr
character(len=😀, parameter :: fmta32 = '(A32)'
read(unit=5, fmt=fmta32) mystr
will read up to 32 ASCII characters from console input into mystr. If you give it fewer characters, the remaining characters are padded with blanks; no need to trim \n. \n is a record separator, not part of the record. You will never see it.
If you give it more than 32 characters, mystr is filled with the first 32 characters and the rest of the characters are ignored. You don't have to worry about \0 because mystr is fixed length; \0 never enters the equation because this isn't C. Try to force a buffer overflow all you want - mystr is 32 characters long by definition and there's nothing anyone can do to change that.
None of this changes if you change the edit specifier in fmta32 to '(A)' - mystr gets at most 32 characters because that's how it's defined.
"But I don't know how long my incoming string is!" I would suggest this is a problem with setting requirements because I very sincerely doubt you can't set a reasonable upper limit on your input. I know, it's heresy in modern computing to set hard limits but that opens us up to lazy wasteful design. Is this input a path? Take the longest path on your filesystem and double it - done. If it breaks for someone, refine requirements and modify the code.
"But then every string I read will be huge and I'll run out of memory!" Fine; read each input string into a big fixed string then use adjustl() and trim() to left-justify and trim trailing spaces and stuff the results into an allocatable character variable. You pay for that with some memory accesses (time) but you save on memory (space).
"But I don't want to spend the time copying the data!" Ok, are you sure you want to do massive amounts of text processing in a language oriented toward numerical computation? You might want to rethink your choice of implementation language. Or punt this function off to another language and link to it via Fortran's interface to C. Or you might be prematurely optimizing - how much do you understand about how your code will be used in practice? Do you have an actual performance problem or a reasonably predictable issue? If not, maybe deal with that if/when it arises.
The same issue arises when dealing with arbitrary-length lists of input. I often deal with this sort of issue by reading input into a linked list, counting the elements, allocating a variable-length array, copying the elements over, then deleting the linked list. There's no standard library of collections and data structures so it's DIY or do without. It sucks but nobody wants to spend unpaid effort to build consensus on what goes into a curated standard library and push it through the Fortran language committee. I'm convinced that the only language features that get added today are HPC conveniences for the nuclear weapons complex (see coarray Fortran) - whatever the people paying for large numbers of Intel Fortran licenses want.
Regardless, Fortran input is straightforward if you are reading mildly formatted text files and picking out short strings and numbers. Pretend you're reading from a stack of punch cards - the length limit is far larger than 80 characters but input goes through an implicit readline() step so you never see \r or \n.
You can also open array of strings as a file and use read() and format() for parsing - the keyword to look for is "internal file". I mean, if you really need to write a recursive descent parser but also have random access to the source lines, you can do it. Scanning is a little weird but it's completely doable.
Output is similarly record-oriented - if you're trying to write without advancing, consider compositing output to an allocatable character string; just write the string when you're done appending to it. The edit specification minilanguage can do basically whatever fprintf can do without nearly as much weird punctuation. Just don't expect it to act like stream I/O; this is an application oriented language not a low-level systems language so you don't get (or generally need) fine seek control. You get rewind() and that's about it.
mcc
in reply to arclight • • •@arclight The input is a grid of ASCII characters.
github.com/mcclure/aoc2024/blo…
I am finding STREAM mode from FORTRAN 2003 entirely adequate so far.
aoc2024/04-01-wordsearch/data/sample-2.18.txt at stable · mcclure/aoc2024
GitHubOblomov
in reply to mcc • • •mcc
in reply to Oblomov • • •Oblomov
in reply to mcc • • •mcc
in reply to Oblomov • • •Jason Bowen 🇺🇦
in reply to mcc • • •arclight
in reply to mcc • • •You may be missing a call to COMMAND_ARGUMENT_COUNT() which gives you the number of arguments intel.com/content/www/us/en/do…
Be aware the Fortran I/O is record-oriented. Streams are a C thing from the early 1970s - you have to jump through a lot of hoops to get stream I/O working in Fortran. It's not worth the hassle.
There's a certain subtle and archaic magic to Fortran I/O and for greatest happiness, do not expect it to work like C. In fact, forget that C even exists.
Array indices start at 1 because normal people start counting at one, not zero. (You can set the index bounds of an array to anything you want but you will absolutely regret it.)
Arrays are in column-major order which is pretty much opposite every other language you've used. This will likely trip you up.
Say you've dimensioned A(2,3,5) - 30 elements total in three dimensions or 'ranks'. You'd be tempted to nest loops outer to inner as i=1:2, j=1:3, and k=1:5 and reference elements as A(i,j,k) in the innermost loop. This will have awful memory lookup performance because i is the fastest moving index, followed by j, followed by k. You will typically see nested loops arranged like
do k = 1, 5
do j = 1, 3
do i = 1, 2
A(i,j,k) = whatever()
end do
end do
end do
Note that if whatever() returns a scalar, you could just do
A(1:2, 1:3, 1:5) = whatever()
or
A(:,:,😀 = whatever()
or just
A = whatever()
And get the same behavior without having to worry about efficient memory access. Array operations are your friend - welcome to vectorized (SIMD) optimization with zero effort on your part. Need to initialize A to zero? `A = 0.0` and you're done.
Oh, and numeric types matter. A lot. 3 / 2 = 1, not 1.5. Why? Because integer divided by integer yields an integer. 3 is different from 3.0 which is different from 3.0d0. More formally, these three literals are 3_int32, 3.0_real32, and 3.0_real64 (iso_fortran_env contains definitions of 'kinds' for each of the numeric types.) Type and kind inference and compatibility rules are another rabbit hole of complexity. Remember your discovery of the aint() function? There is also dint() which converts real64 (aka 'double precision') to int32. aint() and dint() are deprecated; int() has some multiple dispatch magic to send whatever numeric type you pass in to aint(), dint(), etc. under the hood. This is another rabbit hole of the Fortran type and object model but for now, all you need to remember is to use the generic forms of int() and real() and to be careful specifying numeric literals. This is a language that cares very deeply about numeric precision and it expects you to be explicit about what you want. It's very good about giving you what you ask for but it also expects that you know what you're asking for. Every new Fortran programmer almost immediately gets bitten by the 3 / 2 = 1 issue. Computer math is very different from formal math, ℤ is not a subset of ℝ here - they are distinct and not necessarily interchangeable or compatible.
This brain dump is getting way too long. Sorry about that.
There are file units, not file handles. FORTRAN was developed for the the IBM 704 which did not have a CRT (in that era, a CRT was more likely to be a memory device not a display). Historically, units may be console, keyboard, printer, tape (magnetic or paper), disk, card punch, card reader, drum, or disk. By convention, console input is unit 5, console output is unit 6. You've already discovered iso_fortran_env which formalizes this convention with standard names.
iso_fortran_env is basically half of Fortran's standard library. There are a few others, mainly relating to IEEE math and C types for cross-language programming.
One of the irritations with Fortran was the need to manually keep track of which unit numbers were previously assigned or in use (like 5 and 6). Good practice today is to define an integer variable to hold the unit number and pass that to open() under as the newunit argument. open() will find a free file unit and store it in the variable which you'll basically use as a file handle.
Fortran is very good about named arguments to functions and I find it helpful to be a little pedantic and wordy to explicitly name all the arguments passed to functions. `read(6, 10) J` becomes `read(unit=6, fmt=10) J` so it's clear which is the unit number and which is the edit descriptor (another deep rabbit hole of Fortran I/O...)
COMMAND_ARGUMENT_COUNT
Intelmcc
in reply to arclight • • •Stewart Russell
in reply to mcc • • •mcc
in reply to Stewart Russell • • •Stewart Russell
in reply to mcc • • •for computer line printers
Contributors to Wikimedia projects (Wikimedia Foundation, Inc.)Joe Groff
in reply to mcc • • •Aaron Sawdey, Ph.D.
in reply to mcc • • •Hisham
in reply to mcc • • •Dima Pasechnik 🇺🇦 🇳🇱
in reply to mcc • • •you can run modern Fortran in your browser:
dev.lfortran.org/
LFortran
dev.lfortran.orgTachibana Kanade
in reply to mcc • • •mcc
in reply to Tachibana Kanade • • •tef
in reply to mcc • • •programming language
Contributors to Wikimedia projects (Wikimedia Foundation, Inc.)thermonuclear small claims
in reply to mcc • • •mcc
Unknown parent • • •mcc
Unknown parent • • •mcc
Unknown parent • • •arclight
Unknown parent • • •@Petra If you're up for reading git history, a few years ago I methodically modernized a F66 text adventure to F2018. gitlab.com/apthorpe/Castleques…
Refactoring away 750+ GOTO statements in the main game loop was satisfying but the last 10 or so took some pretty severe architectural modification. This code is probably a worst case scenario for untangling IF/GOTO logic.
The binary save file format from 1979 should still work and the game should play about identically to the original, though it accepts both upper and lower case commands now and the output defaults to plain text without the ASA carriage control characters. Builds on Mac, Windows, and Linux with identical source code (no #ifdef nonsense) and will create native installers for each platform if the appropriate packaging utilities are installed.
Bob Apthorpe / Castlequest · GitLab
GitLabmcc
Unknown parent • • •Danilo Piazzalunga
in reply to mcc • • •