Tsoding on Fortran

The streamer “Tsoding” has recently made some videos about Fortran on Twitch. (I don’t endorse the vulgar language or agree with the negative comments made about Fortran.) He relied on the Fortran-Lang resources to get started.

He implements tic-tac-toe in Fortran using raylib (a cross-platform library for videogame programming): GitHub - tsoding/tic-tac-toe-fortran-raylib: Tic-Tac-Toe in Fortran with Raylib

4 Likes

YouTube video here. As @ivanpribec mentions, there are many expletives. But at 16:10 in the video, when Tsoding is appalled by the fact that the type of a variable depends on its first letter when it is not declared and implicit none is not used, he has a point, which has been much discussed here. Earlier he stumbles over the fact that compilers treat source files with .f as fixed format by default, and then he makes the plausible but incorrect inference that a .f90 extension means that the code adheres to the Fortran 90 standard. Reclaiming .f for free source form has also been discussed here.

He mocks the example from fortran-lang of

program read_value
  implicit none
  integer :: age

  print *, 'Please enter your age: '
  read(*,*) age

  print *, 'Your age is: ', age

end program read_value

for being trivial, and I agree. A Fortran program should actually calculate something. I suggest making the print statement

print *, 'Your age in months is: ', age*12

At 33:57 he is perplexed by the fact that random_number is a subroutine that requires a call to be invoked. Fortran subroutines will surprise people coming from languages with only functions, but I like having both functions and subroutines in the language. A call foo(x, y) informs the reader that arguments will likely be mutated and/or that I/O will be performed. Functions can mutate arguments too, but that should be avoided.

Only at 1:54:33 does he figure out that functions return values and subroutine don’t.

The video, posted 20 hours ago, already has 8.6K views. The author has 59K subscribers on YouTube and closes the video by saying he will do more on Fortran.

9 Likes

Thanks for providing a summary. The videos are quite long and I can’t imagine spending five hours watching someone else program or expect anyone else to do it. I just fast-forwarded through them. The author is obviously quite skilled to pick up a language in such a short amount of time, despite being so opinionated. He does raise some valid points which we can perhaps learn from as you’ve suggested.

When I see such videos, I’m always reminded of the “programming as pop culture” quote from Alan Kay who gave a talk on Programming and Scaling in 2011:

So I think what happened is computing has turned into pop culture and the universities are not helping in general, at least not in the US. [emphasis added]

So, Cicero — anybody know a good Cicero quote having to do with the present and past? Let’s check your classical education here. So, you know who Cicero was. He was one of those old Roman guys.

So, Cicero once wrote: ‘He who knows only his own generation remains forever a child.’

On a slightly tangential note, I recently noticed a Tic-Tac-Toe program, in scans of the DECUS Program Library made available on GitHub by Thomas Fabula. I transcribed the 1966 program from the PDF file here: tictactoe.f. I was not surprised when the program compiled succesfully with the Intel Fortran compiler, however I haven’t done any further work to figure out how it works or checked for errors. What I can say is the program is much shorter than the graphical one by Tsoding. The DECUS version “learns to play” by storing games it loses in a learning table.


(Addendum) When I was in the fourth year at university I took a course on numerical methods given by professors from the physical chemistry department. We were given the options to use either Fortran or Excel for the programming assignments. The generation after me used Python, because our representative in the student council complained about why we learn this old language with bad career prospects, and the professor decided to switch to Python. The professor later told me the switch was made primarily because students have a short Python course in the first year, meaning he can build on top of the knowledge they already have. (The same student representative wanted to get rid of quantum mechanics from the chemical engineering study program…) Anyways, my interest in Fortran was a key factor in getting a job at an excellent computing center with some of the latest hardware, so I’m thankful to the professors for their effort teaching me Fortran.

5 Likes

In my opinion, a Twitch streamer doing anything in Fortran is essentially purely positive. See also Introducing the CHADstack - YouTube making a web server in COBOL. Even if the content is purely for entertainment, a programming language being in the mind of people should be viewed as positive.

1 Like

That processor continues to serve the past first. With a different set of options, better suited for those having to deal with the present and consider the future, the processor would issue:

.
p.f(20): error #6477: Fortran 2018 does not allow this statement or directive.
      TYPE 900
------^
p.f(22): error #6477: Fortran 2018 does not allow this statement or directive.
      ACCEPT 901,I
------^
.
p.f(48): error #8871: The nonblock form of the DO construct is deleted in Fortran 2018.   [8]
    8 CONTINUE
----^
.
p.f(80): error #8870: The arithmetic IF statement has been deleted from Fortran 2018.
      IF (IG(I)+IG(J)+IG(K)-15) 13,12,13
---------------------------^
p.f(83): error #7342: The computed GOTO statement is an obsolescent feature in Fortran 2018.
      GO TO (28,28,28,28,28,28,28,28,28),K
------^
p.f(87): error #7356: The PAUSE statement has been deleted in Fortran 2018.
      PAUSE 5
------------^
p.f(132): catastrophic error: Too many errors, exiting
compilation aborted for p.f (code 1)
..

raylib actually has bindings for a large number of languages, but not yet for Fortran.

I know we have some people in this forum who are quite good at making C bindings. In the fun-factor-scale, this is way more important than bits, strings or generics. Once we have it, we can start coding games instead of building computational codes! :slight_smile:

3 Likes

@tyranids, I don’t disagree, if people can pick up a few things about Fortran, that’s positive. On the other hand in the flood of information available today, and further expected to come out of generative AI, I’m starting to think we should become more aware and selective when it comes to information we consume. The posture problems and cognitive issues stemming from prolonged smartphone usage, which I observe also on myself, also make me doubt the value of streamed content.

Anyways, my motivation for sharing the video was the “joy” in seeing someone use Fortran-Lang resources to get started with Fortran. The network effect of exposing 8000 viewers to our website is not negligible.

3 Likes

Allowing people to create the programs they are interested in is a great way to get them using your language. Having those resources freely available and easy to use is also of great benefit, see CUDA from Nvidia vs any-software-support from AMD (I believe ROCm technically works on consumer GPUs, but not officially, not with any support, and not without significant hassle on the user side).

Fortran is never going to be as concise or easy to write as something like Python or Go without becoming completely unshackled from “backwards compatibility first.” Not that I am advocating for that, because I also believe that at this current moment, the only thing keeping Fortran relevant at all are those legacy codes.

For long term, continued relevance, I do believe such a move is necessary, but a more substantial user-base with many current, actively used and developed projects is required first. Fortran currently lacks the infrastructure required of a modern language. Efforts like LFortran, stdlib, and fpm are moving towards that goal.

LFortran - A modern language needs a community compiler that is actively developed and willing to implement language extensions, try new things, respond to user feedback, and push the language forward. A language standard should exist to describe how the language operates so other compilers may implement it if they wish, not dictate how the language is.

stdlib - A modern language needs a standard library. Plain and simple. Should the user be required to download additional packages beyond “install the language?” No. Do they now? Yes. Is that a problem? Yes. Is the build process existing a problem? Yes.

fpm - A modern language needs a package manager to allow easy use of other peoples’ code, as well as creation and sharing of new libraries. Whether in the future “Fortran” is synonymous with “LFortran” or “fpm” doesn’t really matter. What matters is that new users can find + install a single package that gives them access to a fully featured compiler, a standard library providing many common utilities with easy to use interfaces, and a package manager to bring the entire ecosystem together.

3 Likes

A standard can not be just about listing the existing practices, it has also to keep some consistency, sort out the relevant evolutions, etc, and following a kind of “constitution” (what is the purpose of the language in the first place).

Even the most “community-driven” projects have a central authority that ultimately decides. And when a part of the community disagrees too much, some fork can happen.

Right, I don’t necessarily think we are disagreeing about this point. A benevolent dictator is always the most effective form of leadership, in theory. In many cases it often does not work for the users (programmer community, etc.), see numerous real world autocracies. However, for some things it can work quite nicely - see founder-led companies, Linux, any number of single-person FOSS efforts.

However, a programming language meant to adhere to a standard will greatly struggle to evolve when the entity responsible for maintaining and releasing revisions to said standard does not also do the same with an actual implementation of the language (be it a compiler or interpreter, whatever). It is difficult to adapt to the needs of users when the standard itself is rather divorced from a language implementation - that is what I am trying to point out. It’s just hard in that case to prototype, experiment, and actually test ideas in order to receive feedback and iterate on design with that model.

1 Like

This really spoke to me today, I did a little bit.

Based on that Tic Tac Toe example it was really easy to get started. GitHub - tsoding/tic-tac-toe-fortran-raylib: Tic-Tac-Toe in Fortran with Raylib

It really seems not that bad, there are just many functions to implement: raylib - cheatsheet and some pains like iso_c_binding’s integer(c_int8_t) is the same as integer(int8) from iso_fortran_env (meaning it’s not unsigned int8), so some fiddling with things like RGBA values and other stuff I suspect will be nicer with some helper functions.

Just to get a blank window like this was pretty easy, click to see.
module raylib_bindings
use, intrinsic :: iso_c_binding, only: c_int, c_char, c_bool, c_int8_t
implicit none
private

    public :: init_window, window_should_close, begin_drawing, end_drawing, draw_fps, color, clear_background

    type, bind(C) :: color
        integer(c_int8_t) :: r = 0, g = 0, b = 0, a = -128 !! defaults to BLACK
    end type color

    interface
        
        subroutine init_window(width, height, title) bind(C, name='InitWindow')
            import; implicit none
            integer(c_int), value :: width, height
            character(kind=c_char) :: title(*)
        end subroutine init_window

        function window_should_close() result(res) bind(C, name='WindowShouldClose')
            import; implicit none
            logical(c_bool) :: res
        end function window_should_close

        subroutine begin_drawing() bind(C, name='BeginDrawing')
        end subroutine begin_drawing

        subroutine end_drawing() bind(C, name='EndDrawing')
        end subroutine end_drawing

        subroutine draw_fps(posX, posY) bind(C, name='DrawFPS')
            import; implicit none
            integer(c_int), value :: posX, posY
        end subroutine draw_fps

        subroutine clear_background(color_to_set) bind(C, name='ClearBackground')
            import; implicit none
            type(color), value :: color_to_set
        end subroutine clear_background

    end interface

end module raylib_bindings

program main
use, intrinsic :: iso_c_binding, only: c_int, c_char, c_null_char
use, non_intrinsic :: raylib_bindings, only: init_window, window_should_close, begin_drawing, end_drawing, draw_fps, color, &
                                             clear_background
implicit none

    integer(c_int), parameter :: window_width = 800, window_height = 600, x_corner = 0, y_corner = 0
    character(kind=c_char, len=*), parameter :: window_title = 'All The Fortran Games Run Like This'//c_null_char
    type(color) :: black_background

    call init_window(window_width, window_height, window_title)

    do while (.not.window_should_close())
        call clear_background(black_background)
        call draw_fps(x_corner, y_corner)
        call begin_drawing()
        call end_drawing()
    end do

end program main
1 Like

Both are already fixed in LFortran — by default “implicit none” is enforced and I already started getting into a habit of not using it, and I must say it’s really nice! Regarding .f, we should absolutely reclaim it. LFortran already treats it as free-form.

5 Likes

From what I can see there are representatives of all the major Fortran compiler “vendors” in the J3 committee (I’m not sure about gfortran, though), and also representatives of major HPC hardware vendors, so it’s difficult to say that there is a divorce at this level.

But admittedly, most of these vendors do not lead the evolution in their implementations.

What you are maybe meaning is that the development model of Python or Julia, where the entity that “owns” the language is also the one that produces the reference implementation (which is sometimes the unique implementation) is more effective/efficient. It can be. On the other hand C++ is highly successful too, while being managed in a similar way to Fortran AFAIK.

Me too getting into a job where I will work on Fortran for developing Finite Element software for offshore structures simulations. At last my dream came true. During the interview itself I have briefed them about this website and the community, as they were feeling repentant using Fortran - due to lack of modern resources.

9 Likes

This is just to satisfy curiosity: if you don’t mind sharing - was quantum mechanics a requirement toward graduation in the chemical engineering program or an elective?

Requirement. The topics covered in the course where the oil droplet experiment, the Michelson-Morley experiment, and all the way to the structure of the hydrogen atom with solution of the Schrodinger equation.

You can view the entire syllabus here University Study Programmes: FKKT under the box University Study Programme Chemical Engineering → Course Syllabus. Quantum mechanics was in the 4th semester of the 3-year bachelor programme.

2 Likes

This isn’t exactly my field, but in order to understand chemical kinetics and thermodynamics in the modern way, a student would need to know statistical mechanics based on quantum theory. Of course these topics were developed originally in the 18th and 19th century based on classical mechanics, but the modern approach is now based on quantum mechanics. At the undergrad level, a student would not need to know these topics in depth, but some reasonable level of exposure is appropriate to prepare them for the real world where they might need to go into more depth in some particular application area.

2 Likes

I really share the sentiment of Tsoding regarding Fortran, especially that this “language f-s you up in a completely new way each time”. When coming from other languages like C++ and Python and was learning Fortran starting my PhD program, I was shocked to discover the “implicit save” behavior, I was shocked to discover that you are not allowed to invoke a method of a returned object (like a() % b() % c()), I was shocked to learn the completely inconsistent behavior of the assignment in many situations, I was shocked to learn that in methods of parametrized derived types you need to re-implement (copy-paste) the code for each kind that you want to handle, I was shocked by inconsistent invocation of destructors across the implementations. It was crazy to me that you can leave such embarassing shortcomings in already a very basic language. While it may sound harsh, Fortran is actually a restrictive language, that could have a lot of potential due to its simplicity, but has these quirks you run into, and if you try to make anything slightly more complicated, you hit this or that wall, as he mentioned. And sometimes the reason is not even complication, just poor design (as in the examples above). I have been following Tsoding for a long time, watching his twitch streams is relaxing to me as a working background, and his opinion is very similar to my first impressions from a few years ago. So rather than totally discrediting, I would rather take it as an unbiased opinion outside of Fortran community. I feel that in Fortran we get used to not having different basic features and having to work-around some quirks, and over the last few years I also have learned to avoid some features and write code differently from what I would typically do, but in the end there are out there faster and more flexible languages, to which people will be migrating until Fortran becomes relevant.

5 Likes

Many valid complaints above in my opinion. Fortran carries with it a lot of baggage from very early days of programming. I don’t love the kind system either, since it’s much easier to think of each type(kind) as a completely different data type.

All that said I’m somewhat curious what faster languages people theoretically would be migrating to. More flexible languages sure, but it was my impression that for most tasks, a competent programmer is able to achieve roughly the same speed in C, C++, or Fortran. Unless you’re talking about stuff like inline assembly and explicit SIMD vector instructions, at which point I’d concur that Fortran will never give you the same speed because the opinion “that’s the compiler’s job” seems very popular. I can’t say that I agree with that sentiment, given Fortran’s self-proclaimed focus on speed, but that’s where we are…

The main reasons I see Fortran codes being rewritten to C++ is that 1) no new computer science graduates know Fortran, 2) computer science is the degree hiring managers look for when searching for software engineers, 3) in the minds of most people, Fortran == FORTRAN 77, if not something older.

1 Like

Back in time I learnt Fortran before any other serious langage (well, I learnt Pascal at the same time actually, and did a lot of BASIC when I was young, and a bit of assembly), and I was shocked as well by many things in C/C++ afterwards.

1 Like