Wait… usenet is still… alive?!?!

In my previous post, I described getting re-acquainted with Fortran after 38 years and discovering that the language had really added some nice features over that time.  I also mentioned how my “curly brace bigotry” was starting to thaw out.  Well, now let’s talk about what I’ve learned over the past week.

First things first, like a good OpenBSD user, I found the mailing list for the GNU Fortran compiler and sent a question to it.  Wrong!  That list is for people working on the compiler itself, not for dumb n00b questions like mine.  Oh whelp.  They were pretty friendly about pointing me to the last place on earth I’d ever expect to be going – usenet.

For those of you who aren’t greybeards like me and have no idea what usenet is, I’ll enlighten you.  Back in the dark ages of the internet, when we used dial-up access, bandwidth was very dear to everyone – even the servers on the Internet itself.  Usenet was essentially a de-centralized message board that you could download information from in phases.  First, you pulled down the list of boards themselves, then when you selected your board, it pulled down the most recent topics, then when you clicked on a topic, you would get the actual text of the topic and any replies to it.

The topics were arranged hierarchically like comp.os.bsd and such.  There was a creepy part under the “alt” heading that had such jewels as “alt.wil.wheaton.die.die.die” for people who didn’t like the character he played on Star Trek TNG.  At one point, I could swear remembering that usenet went away and was really nothing more than an archive that some sites saved.  Apparently I was wrong because my friends on the compiler mailing list directed me to comp.lang.fortran.  On a side note, one of the folks on that list was very kind and helped kick start some of my early learning.

After a brief internet search, I found a link and clicked on it.  I don’t know if I should be seeking professional help or if others have dreams like this, but occasionally I have a “neglect dream” where (in the dream) I suddenly remember something I was supposed to have been doing but wasn’t – like feeding my non-existent giraffe.  Well, the feeling I have in the dream when I head out to where the giraffe lives (expecting at the least a thin and angry horned long-neck horse) was the feeling I had clicking on that link.  However, instead of a dead or murderous giraffe, I found a healthy message board that used Google Groups.

In addition to posting questions when I got stuck and reading code on the Internet, I also downloaded and read (yes – cover to cover) a Fortran programming book called “Introduction to Programming with Fortran:  Third Edition” on my Kindle web app so I could read it in my browser on OpenBSD.  After perusing this information, I was even more impressed with what Fortran has grown up into.  One of the folks on the comp.lang.fortran group pointed out that the oldest date he was aware of was October 15, 1956 (an old IBM 704 manual apparently) so we are essentially looking at Fortran’s 60th birthday in a few months.  That’s a long time for something to stay this relevant.

OK.  Time to dive in.  My use case was to create a string class and then add a subclass to it that uppercased all strings before storing them.  Pretty simple, eh?  You’d think until you learn that, while Fortran has great numerical and scientific intrinsic functions and features, it really lacks character handling capabilities.  No problem, the Internet to the rescue.  I found a string upper-casing and lower-casing implementation that I baked into what Fortran calls a “module”.  Essentially a module is a way to encapsulate types, code (functions and subroutines) and data.  Modules can be in stand-alone files and can be included into another piece of code using the “use” statement.

module foo_m
...
end module foo_m

program bar
use foo_m
...
end program bar

As you can see from the above example, this is quite similar to the “require” functionality that you see in Javascript programs of the Node.js variety, the “#include” feature of C/C++ and the “using” feature in C#.

After some pointers from the kind folks on the comp.lang.fortran mailing list, I cobbled together a bit of a style guide that I tried to follow as I built my example.  By the way, if you would like to see the finished product, take a look on github and you should have a fully buildable version on OpenBSD.  If you want to build this on another platform, you’ll probably have to change from “egfortran” to whatever the gfortran compiler is called on your platform (most likely gfortran).

My string_utility.f90 file ended up with the following structure:

module string_utility
implicit none
private
public :: ucase
public :: lcase
contains
pure function ucase(in_string) result(out_string)
character (len=*), intent(in) :: in_string
character(len(in_string) :: out_string
...
end function ucase

pure function lcase(in_string) result(out_string)
...
end function lcase

Some things to point out here.  The use of “implicit none” brought back some fond memories.  FORTRAN used to automatically type declared variables in a really cute way.  If the variable name started with a letter between ‘I’ and ‘N’, it assumed it was an INteger.  Ha!  Since we want to declaratively type things these days and not have “odd” side-effects from features like that, implicit none turns this feature off for the module.

Fans of other OO languages like C++, Java, etc. will recognize the use of “public” and “private”.  Fortran is public by default, so putting the private declaration at the top of the module flips this to the way I feel most comfortable.

The “pure” keyword isn’t really needed perhaps, but I threw it in to illustrate that feature of the language.  Fortran is very focused on parallel programming and this feature is essentially a compiler hint that the code in that procedure is deterministic and can be ran in parallel if necessary.  For a better description than a n00b like I can produce, take a look at this stack overflow post.

The last interesting bit in this code snippet is how I declared the return type from my function.  You can do it two ways, the traditional supply-the-type-before-the-name way (in which case you specify the return value by assigning your result to the name of the function in its body) or the way I did it here where I have a specific variable I declare to hold the result.  No preference, this just looks tidy to me.

By the way, it is probably worth pointing out that, unlike the C languages and their offspring, Fortran has two types of procedures – functions and subroutines.  A function returns a value and requires no special calling syntax and a subroutine returns no value but requires the use of the call subroutine_name() syntax to invoke.

The next thing we’ll talk about is how you build the equivalent of a class from the curly-brace languages.  That is done in Fortran by creating a type in a module.  Take a look at the following code skeleton:

module string_m
implicit none
private
type, public :: string_t
private
character(:), allocatable :: str_m
contains
private
procedure, public, pass(this) :: get_value => get_value_string_t
...
end type string_t
...
end module string_m

Ok.  There are many interesting things going on in this code.  In the type declaration, you see me creating a type called “string_t”.  The “_t” bit is just convention, it isn’t syntactically necessary.  The private variable “str_m” is an “allocatable” character array, or what I would call a “string”.  You also see a public procedure called “get_value” that is aliased to a local function I called “get_value_string_t”.

Finally the “pass(this)” part is some cool magic.  This is where you declare the equivalent of a “this” pointer in C++ that contains a reference to the object in who’s context your procedure is being invoked.  The slick thing is you can call it whatever you want so you aren’t tied to a particular name.  Plus (to me at least) the fact that you have to explicitly declare it takes away some of the “magic stuff” in C++.

To subclass this little gem, it is pretty straightforward.  Take a look at the following code skeleton to see how that happens in another module:

module ustring_m
use string_m, only : string_t
use string_utility, only : ucase
implicit none
private
type, public, extends(string_t) :: ustring_t
contains
procedure, public, pass(this) :: set_value => set_uvalue
...
end type ustring_t
...
end module ustring_m

OK.  Lots of stuff going on here.  For one, did you notice the new “use” feature I pulled out of the air?  If you say “, only :: ” and list a set of components, only those components are used from the included module.  This helps you avoid unintended name space collisions from crud that happens to live in a module.

You can see from the “extends” piece of syntax, that this is how you subclass your base class.  Finally, if you look at the procedure, you see that I am overriding the “set_value” procedure from the base class and mapping it to the local function that I named “set_uvalue”.

At this point, I knew enough to be dangerous and, as is my speciality, decided to soar over the tips of my skis and crash into the mountain – I had read about operator overloading and decided to create an overload of the equals operator!

Boom!

Well, that was painful.  Back to the comp.lang.fortran group for some healing and education.  I learned that, while you can overload operators in Fortran, what I wanted to do was overload “assignment”.  After a lot of back and forth with some incredibly patient people out there, I discovered the solution that makes all of this make sense and be pretty simple to do.

You declare the assignment operator in your base class and use the ability to alias the names of procedures in your subclass to overload the actual methods performed.  Here is how it looks in the base class:

type, public :: string_t
private
character(:), allocatable :: str_m
contains
private
generic, public :: assignment (=) => string_t_assign_string_t, &
string_t_assign_character
! Procedure declaration for internal methods
procedure, private, pass(lhs) :: string_t_assign_string_t, &
string_t_assign_character
end type string_t

Believe me, this looks way cleaner than the messes I created along the way to learning how to do it.  Oh, and did I mention that Fortran uses the exclamation mark (bang) for comments?  It feels slightly ironic to me like, “Holy crap!  I’m actually putting a comment in my code!  Can you believe it?”  I used to work with a guy who said that anyone not smart enough to understand his code by reading it shouldn’t be in there in the first place – that’s why he never commented it.  😉

So the interesting bits here are the use of the “generic” keyword.  This allows us to genericise what can be on the right-hand side of that assignment operator.  Very similar to generics in other languages.  Finally, notice that we have to declare the actual procedures that do the assignment (one from a string_t type and a second one from a character or character array) twice.  Once in the mapping and a second time for the actual declaration.

The implementation of the procedures is pretty straightforward:

elemental subroutine string_t_assign_character(lhs, rhs)
class (string_t), intent (inout) :: lhs
character(len=*), intent (in) :: rhs
lhs%str_m = rhs
end subroutine string_t_assign_character

The only piece of magic here is the use of the keyword “class” so that you can tell the compiler you might want to allow someone to override this procedure later in a subclass.  If you don’t want that, just use “type”.  Finally, I picked this method to show the implementation of because of the use of “elemental”.  This tells the compiler that you can pass a single character or an array of characters.

One thing that a good object needs is a constructor in C++ to initialize internal data, etc.  Figuring this out in Fortran was a little challenging.  What I ended up with is as follows:

module string_m
implicit none
private
type, public :: string_t
private
! Internal private character store
character(:), allocatable :: str_m
contains
private
end type str_t
! Class constructor
interface string_t
module procedure string_t_constructor
end interface string_t
contains
type (string_t) function string_t_constructor()
string_t_constructor%str_m = ""
end function string_t_constructor

So the trick here is to declare the interface, then actually define the function in the contains section of the module, returning a type of “string_t”.  I’m not certain if the “_constructor” is convention or required.

Now I can build a little test program to exercise my classes like this:

program fortranString
! Pulls in public interface for our String module
use string_m, only : string_t
use ustring_m, only : ustring_t
! Prevent default I-N integer assumption
implicit none
! Declare local variables
type (string_t) :: string1
type (string_t) :: string2
type (ustring_t) :: string3
string1 = "Bonjour"
print *, string1%get_value()
end program fortranString

As you can see, we can call the methods in the classes, use the assignment operator and all sorts of fun things like that!

So, in conclusion, Fortran is a pretty cool language.  The syntax is a little different that a curly-brace guy like me is used to, but once you figure it out, it’s pretty easy to use and has a very nice feature set. Again, if you’d like to look at a functional complete example, check out my source repository on GitHub.

I’m going to do a third post in this series where I actually build a modern web application using Fortran for the middle tier (I’m thinking I need a cool name like LAMP or BCHS so maybe FARM – Fortran, Apache, REST and mySQL?) but that’s for another day.  Hope you enjoyed reading this as much as I enjoyed learning it.

Have you seen FORTRAN lately?

I’m familiar with the FORTRAN programming language.  Heck, the first formal programming class I ever took was in 1978 in FOTRAN-IV on punched cards (don’t laugh kids, I’ll tell you to get off of my lawn if you do).

My next exposure to this venerable language was in college when I took my intro to CS course in the amazing, whizz bang “new” FORTRAN-77.  In that class, I got done with my final so quickly that I spent the rest of the time using VT-100 escape codes on the VAX-11/784 to animate a beer truck across the terminal – again written in FORTRAN-77.

My final trip to FORTRAN-ville was a year later in an algorithm analysis class where we had to solve the “Towers of Hanoi” problem using recursion in both FORTRAN-77 and Pascal.  The only catch – FORTRAN-77 didn’t support recursion so we had to build and manage our own stack.

All of this left me with the feeling that FORTRAN wasn’t a very exciting language and was quite old-fashioned.  Not too long after that, I learned C and my path to the dark side began.  I went from C to C++ and eventually to things like Java, Javascript and C# – quite happy in my little curly-brace world.  And by the way, the only true way to nirvana lies in putting the curly brace on a separate line from the IF statement now doesn’t it my disciples?!?!?!  Bwahahaha…

OK.  Fast forward to a couple of weeks ago.  I had been reading about the BCHS (pronounced “beaches”) web programming stack (see this page for more details) which essentially is using C for your middle-tier code with CGI to write web applications.  Now, regardless of whether or not this was serious or a joke (there seemed to be some debate on this on Reddit at the time), it got me thinking.

I remember CGI programming from the mid 90’s.  Essentially the idea is that you have a chunk of code running on the web server (be it a script or compiled code, it really doesn’t matter) that kicks out HTML for its output.  This allowed you (way, way, way back in the day) to access crazy things like relational databases and such to generate dynamic web pages and perform I/O with users.

I went down the path that said, “Hey.  If you can do this with C, why not other languages?”  I tried thinking what the most absurd, crazy, old-fashioned thing you could use and came with COBOL!  Of course!  That would be the funniest thing imaginable.  Unfortunately, even doing a multi-year stint as a mainframe CICS programmer back in the 80’s and 90’s, I never used COBOL (I used PL/I for those who were curious – a pretty cool language for its time actually).  This left me with FORTRAN – the language I knew from college and my brief punch-carded middle-school experience.

I did some sniffing around in the ports tree and discovered that OpenBSD has the GNU version of FORTRAN and it appears to be fairly recent.  I did some further investigation and hit a wall – we only support FastCGI with our httpd web server and surely that wasn’t the same thing as straight up CGI that I remembered.  After some searching, I confirmed my suspicion – FastCGI counts on a long-running process that the web server communicates with via sockets so that it doesn’t have the overhead of firing up and tearing down a process for each web transaction (boy they sure got smarter after the mid 90’s on this web stuff <grin>).

Not to be deterred, I decided to use the Apache web server from ports.  Installing that was pretty simple via pkg_add and turning on CGI access wasn’t that tough either.  All I had to do was uncomment the LoadModule call to the cgi_module, add a ScriptAlias to a virtual /cgi-bin directory (to contain my scripts outside of the htdocs tree) and add the ExecCGI option to my htdocs directory tree.

From there, I wrote a little shell script to test things and stuck it in my /var/www/cgi-bin directory as testcgi.cgi:

#!/bin/sh
echo "Content-type text/plain"
echo ""
echo "Hello world!"

I then invoked http://127.0.0.1/cgi-bin/testcgi.cgi and got the content “Hello world!” in my web browser.  Note the blank line after the content-type header – if you miss that, you will suffer with 500 errors until your web searching fu teaches you the error of your ways.

Now for the fun, let’s use FORTRAN to write our CGI script.  This should be crazy.  I can’t wait for all of the uppercase characters and sequence/line numbers in my xterm under vim.  I’ll fee like Indiana Jones in the Temple of Doom or something – a crazy technology archaeological expedition!  Off to wikipedia and the web to re-learn this language enough to write out strings.

Well, the first thing I learned was we are much more polite in this millennium than we were in the last – we don’t shout the name of the language any more.  FORTRAN (which stood for FORmula TRANslation) was now Fortran.  Also, there were new standards that were established after the 1977 version I was used to.  They had one in 1990, 1995, 2003 and 2008.  Apparently there was even a 2015 version undergoing standards ratification.  Huh.  Looks like people still use this crazy old thing.

Some more research turned up an interesting fact – 15% of the world’s software is written in Fortran.  I started looking at some of the language features that had been added over the years (more out of curiosity than for any other reason) and was shocked, nay horrified to find out that they added recursion.  That would have made my data structures class in college a heck of a lot easier!

I kept looking and discovered other interesting things.  For one, user defined types!  We didn’t have those in FORTRAN-77.  Also fun things like object oriented features, operator overloading, free-form formatting, case-insensitive intrinsic functions, generics…

Holy crap!  I suddenly felt like the prototypical old guy at the high school reunion who discovered that the nerd you remembered had grown up to be attractive and successful.  My world-view (the one that said all curly-brace languages were naturally superior to all others) was in jeopardy.

The only thing that could save me would be if our Fortran compiler on OpenBSD was too archaic for any of this funny-business to work.  Then I would be justified again.  My heart rate started to settle down to a more normal level at this thought.

I started sniffing around in the ports tree and discovered I already had most of what I needed installed.  With the latest (in our tree at least) gcc installed, all I had to do was add the g95 compiler via pkg_add.  I did so, and then tried invoking it with a simple ‘g95 –version’.

No joy.  No binary with that name on my system.  Huh?  I did a ‘find / -name g95’ and still came up dry.  I then did some web searching (notice I don’t say “googling” any more now that I’ve switched to duck duck go for my web searching) and discovered that, silly me, it isn’t called “g95” it is called “gfortran”.  OK, I tried that ‘gfortran –version’.

No joy.  No binary with THAT name on my system.  WTF?  After some more searching, I discovered that we call it “egfortran” on OpenBSD and all was right with the world.

I tried my little test program that I did before with a shell script, but this time did it in Fortran as testcgi.f and came up with:

program testcgi
print *, "Content-Type: text/plain"
print *
print *, "Hello World!"
end program testcgi

When I used the command-line ‘egfortran testcgi.f’ I was expecting to run a.out and move on with my life.  Nope!  All sorts of crazy error messages.

After some more searching, I found the ‘-ffree-form’ compiler flag.  It worked.  (Edit:  I later have learned that if you use a .f90 file suffix, the switch is not necessary.)  I copied the resulting a.out binary into my /var/www/cgi-bin directory and renamed it to testcgi.cgi and went back to my browser.  Drum roll please….

Fail!  I got a 500 error.  This really stymied me for quite some time until I picked up on a subtle thing.  When I ran my binary from the command-line, I suddenly noticed that every line of text was preceded with a blank space in column 0 (or would that be column 1 in a Fortran world?).  Anyhow, after some web searching I discovered that I could use a format specifier and all would be fine.  This left me with the following, which worked:

program testcgi
print '(a)', "Content-Type: text/plain"
print '(a)'
print '(a)', "Hello World!"
end program testcgi

So now that I have scratched that initial itch, I’m curious to see how far Fortran can take me with a more interesting problem to solve.  Look for an upcoming post that will delve into that.