Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: A minimal Fortran TCP client and server (github.com/modern-fortran)
110 points by milancurcic on Oct 30, 2019 | hide | past | favorite | 45 comments



In grad school, I revived some FORTRAN66 code for aircraft sizing. (You can probably download an equivalent model from Dan Raymer's website as an Excel workbook.) This was not its first revival, according to the comments in the code. That was when it was transferred from paper tape and adapted to run on VAX/VMS. Nor was this its second revival. That was when my advisor had made the VAX/VMS version work on SunOS when he was in grad school. No, this was its third revival, wherein I took the SunOS version and made it run on modern Linux. I'm sure a seasoned veteran would have known about the magic compiler flags that made it not produce garbage, but it took me several days of trial and error, and reading the gfortran man page. Along the way, I got to learn about Hollerith constants! Some day, I'm sure another generation of grad students will renew the great tradition, adding their own comments below mine.


You would have been much better off nowadays, because the legacy vendor-specific features have mostly landed into gfortran (recently) behind flags. This is specifically to aid porting off old compilers onto GCC/Clang.

https://github.com/CodethinkLabs/fortrantools/blob/master/RE... (And related repos...)


I had to touch a little bit of Fortran 77 when I interned at Lockheed Martin nine years ago.

While I don't know that I would use Fortran for anything nowadays, I do kind of have to appreciate how completely simple Fortran was in comparison to my favorite language of the time, C++ (I hadn't learned Haskell or Lisp very well at the time so I didn't know better :) ).

I haven't touched any later standards after 77; is Fortran still technically not Turing complete?


Many of the libraries used by popular Data Science/Vis tools today (Matlab, Numpy etc) use BLAS and LAPACK which are written in FORTRAN


BLAS now has a number of non-Fortran implementations, inlcuding ATLAS[1] (C) and and Eigen[2] (C++). LAPACK is still Fortran-only, although many libraries (including the two mentioned above) implement a subset of LAPACK in other languages.

[1] http://math-atlas.sourceforge.net/

[2] https://bitbucket.org/eigen/eigen/src/default/Eigen/src/misc...


Yes, for performance. If you need something to be fast and yet portable, Fortran is still the #1 language of choice, especially in supercomputing and finite element analysis fields.


Plus on the topic of Data Science, R is written in a mixture of FORTRAN and C!


Yes, the core of R is written in Fortran because short of writing assembler code by hand, Fortran compilers generate the fastest machine code.


Modern Fortran is practically a totally different language (although, maybe surprisingly, still compatible with older standards). In fact, it is a quite comfortable language to use if you need to work with vectors and matrices. In very rough lines: numpy array syntax with better than C performance.


> I haven't touched any later standards after 77; is Fortran still technically not Turing complete?

Fortran has been Turing complete since its inception in 1957 :).


The argument against f77 being Turing-complete is that you can't dynamically allocate memory, or specify infinite arrays, or recurse. You have to declare a finite size for everything. So a program embodies a fixed limit on how big a problem it can handle.

In C (the abstract machine with arbitrary-sized ints) you can allocate an arbitrary amount of memory. It may, of course, not run on any given machine. But the language itself allows it.


f90 introduced recursion and allocatable (dynamically sized) arrays.

So (in reference to tombert's comment), f90 and beyond doesn't have those limitations. It also introduced conveniences like operator overloading and element-wise array operations, so I think it's a really simple/convenient language for basic scientific computing, if you want to code up some algorithm. That said, I always reach for Julia instead.


If that makes F77 not Turing-complete, nor is C. There is a finite amount of memory you can allocate in C, since a pointer must have finite size, implying there is a finite number of things it can point to.


The C language specification doesn't require a pointer to have finite size. Just because every C implementation has a limit, it doesn't mean the language itself does.


Doesn't it imply that it must be finite, because you can use sizeof() to find its size, which yields something of type size_t, which has maximum size SIZE_MAX?


The idea is that theoretically a perfectly portable C program could be written and work on problems of any size given sufficiently large hardware and a compiler implementation that takes advantage of that hardware.

Unlike a Fortran77 program, a portable C program doesn't have to change to support orders of magnitude changes in problem size.


You did not answer the question of SIZE_MAX being the limit. So here it is once again:

> Doesn't it imply that it must be finite, because you can use sizeof() to find its size, which yields something of type size_t, which has maximum size SIZE_MAX?


You could take the exact same C program and run it on a compiler+computer with sizeof(void *) == 64 or 128 or 1000000, and it should handle a correspondingly huge problem.


I am not sure that would be valid. You could also use a defined constant as the limit in the Fortran program. In other words, you could argue that SIZE_MAX is part of the program, the same as the Fortran array size is defined in the program. But I am not sure it would be invalid either... just wondering.


Wouldn't it be possible to, with a really strange number format for integers, define SIZE_MAX as INFINITY? C doesn't require twos-compliment numbers, after all.


> Wouldn't it be possible to, with a really strange number format for integers, define SIZE_MAX as INFINITY?

That's a very interesting question that got me thinking for quite a while and the only conclusion I reached is that you deserve an upvote.


Fortran can read and write arrays to disk so I think that satisfies Turing equivalency.


Out of topic. I recently finished reading "Skunk Works Memoir" and I'm interested in the day-to-day life for a developer there. Would you mind sharing a bit of your experience?


I was only an intern, and I haven't read that book, but it was overall a fun job. I was of a bleeding-heart-pacifist, so I made it pretty clear that I didn't want to work directly on weapons or anything like that and as a result, around 90% of what I worked on was actually C++ working on a camera to help detect mines.

The Fortran I touched was actually in an unrelated department; to what I was doing. Basically there was some old code that needed to be ported to an newer system; it was largely following the Fortran 77 spec so all they needed was an intern to copy the code over to a newer machine, and fix the compiler bugs.


I find it hard to justify why, but I'm always so curious about those legacy systems still running in enterprise-scale companies. I doubt that working on them is anything short of terrifying, but I find it so interesting to hear about what important systems are still out there running just fine on ancient tech.


Linking COBOL and Fortran against C is actually one of the easier things to do. So with these multi-million line systems, often new features are written in C++, minor minor minor bugfixes in the original language, and general maintenance is a toss-up if it's a re-write in C++ or just fix it in the old language. Depends on how fast they need it.

I did some Pre66 Fortran work for a bank, and that was basically the idea. They were in the process of converting internal assumptions of the program from a very particular older mainframe type to a mix of Z/OS and Solaris, and the Fortran/COBOL into something they could continue working with.

Some of the code was very specifically marked as "not for C++", because modern Fortran (2003 at the time) was better for some specific number-based things. But that code becomes a library rather than part of the original monolithic structure. And modern Fortran is actually quite a nice low-level language to play with.

It was actually easier than expected - when the original program was written, and for about the next twenty years following, the entire program and changes were very well specified in multi-thousand page specifications. The newer code was harder to keep track of, rather than the oldest, because at the oldest those documents were 99% accurate, even if you never trusted them to be because of the intervening time.


> Some of the code was very specifically marked as "not for C++", because modern Fortran (2003 at the time) was better for some specific number-based things.

Was that a you-can't-do-that-in-c++ thing or slightly-faster-in-fortan thing? I'm always skeptical about the latter guiding major maintainability decisions on often-specious performance benefit claims.


To expand a bit on other answers: There is a qualitative difference Fortran has by offering

1) built-in multidimensional arrays including Matlab-like array operations. That means every library supports the same format, it's standardized and convenient as opposed to the many formats in C++ Land.

2) performant defaults. When performance is more important than safety, Fortran programs are easier to write and maintain. Arguments are by default pass-by-reference, non-aliased (a major assumption Fortran compilers can usually make to optimize) and their intent as in/out/in out can simply be marked as such.

Fortran:

real(8), intent(in) :: foo

C:

restrict const * const double foo # if I remember correctly


I’m not sure what you mean by “When performance is more important than safety, Fortran programs are easier to write and maintain.” The fact that arrays are not based on pointers makes Fortran a much safer language than C. It’s very hard to shoot yourself in the foot with Fortran. It’s fast and safe


Fortran offers a better developer experience overall for Numerical applications yes. But it is still very foot shootable as I remember - point a pointer at allocatable and the fun can start. Or make everything inout for convenience and/or performance. But yes, compared to C the defaults are also safer, just don't expect Rust.


It’s very easy to shoot yourself in any body part - just disable array bounds checking, drop modules (which means no function call interface checks) and you’re practically back to C-land in terms of memory safety. Of course, the sensible thing to do is to check interfaces and bounds (at least in debug/test mode).


Slightly-faster-in-Fortran. But it wasn't just a slight gain. The system I'm referring to is a multi-national system that processes somewhere in the order of 50-100 million transactions a second (depending on the time of day, and the day itself).

A slight performance gain of 1% by using Fortran has a noticeable effect on long-term economic gains. (It was usually in the range of 5-8% performance improvement, but at the worst was 1%).

Thankfully, the reason I can tell you this, is because they tested it in the real world, splitting all transaction across a large-scale A/B test.

The real-world economic gains from the faster performance more than paid for the occasional development costs of a Fortran-familiar developer, hence why those systems persist in Fortran. They also scheduled re-assessment of this once every five years, knowing it might change one day.


In the areas where you'd want to use modern Fortran (numerics, not TCP servers), it is easily also more maintainable than C++.


Not terrifying at all.. for the most part Fortran-used-like-C looks pretty much like... C. Declare a header signature the right way, call any Fortran function from C, declare any C function with an underscore at the end and constrained to some rules and call it from Fortran. Like other comments point out, there’s nothing “ancient” about the language. You don’t need to hunt for dusty floppies and emulators to boot old OS images from tapes. GCC 9.2 compiles it all.


Yep, compiling Fortran right now with GCC 9.2.0. Modern Fortran is wonderful, and CUDA Fortran is a blast.


Probably no more terrifying than a similarly sized system in C C++ or a more modern stack.

Back in the day I worked on billing system for BT written in Fortran 77 and Pl/1G and that was ok to pick up - we did have an actual genius as a team leader and designer though YMMV


I mean, when you have millions of line of code, it takes many many years to rebuild the system. It may make more sense to abstract away a part of the code and treat it as legacy-API-that-works-fine, and write new code in a new language.


C/C++ compilers matching Fortran performance in numerical work is a relatively recent development. F90 and later said to be pretty ok ergonomically.


And it requires lots of template metaprogramming to actually achieve it, see eigen.

Not to mention all the unsafety issues. while fortran is bleeding fast while keeping safety on.


Note this is free form FORTRAN 90 code; not your grandparent's f77 optimized for card punch entry.


Somewhat interestingly, I believe this is actually Fortran 2003 at a minimum based on the use of iso_c_binding[0].

[0] http://fortranwiki.org/fortran/show/iso_c_binding


Wow, ageist much? My wind model is F77.


Should have picked my words better; great grandparents. I still use f77 code for my day job on occasion.


Is this code on github/online somewhere? As someone who does fluid dynamics in Fortran 90/2018, I'd be interested in taking a look.


All the complexity is in libdill, which is written in C:

http://libdill.org/

... which means they buried the lead pretty deeply, because libdill is an interesting little library: Structured Concurrency in C! From the FAQ:

http://libdill.org/faq.html

> How does libdill's concurrency differ from Go's concurrency?

> No interaction between threads. Each thread is treated as a separate process.

> Channels are always unbuffered.

> choose, unlike select, is deterministic. If multiple clauses can be executed, the clause closest to the beginning of the pollset wins.

> chdone signals the closing of a channel to both senders and receivers.

> Coroutines can be canceled.

And:

http://libdill.org/structured-concurrency.html

> What is structured concurrency?

> Structured concurrency means that lifetimes of concurrent functions are cleanly nested. If coroutine foo launches coroutine bar, then bar must finish before foo finishes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: