On "Learnable programming" by Bret Victor

Surely you've read this essay/manifesto by the omnipresent Bret Victor already. If not, go do it. Then read Sean Barrett's response.


For the short-attention-span readers: TL;DR

  • Programmers who learnt during the 80s have it easier because computers were slow enough to internalise what was going on.
  • Bret proposal's are awesome although I don't know how can we apply them to so many fields.
  • In the meantime and while those incredible proposals are developed, let's start doing whatever is in our hands to make existent software easier to use and understand, API and developer wise.

And now, here's the full version of my comments:

Us, programmers who learnt to code in the 80s with languages such as Logo running in 8-bit computers, have a huge advantage over people who tried to learn later, when computers were faster. Because we could already see how the computer worked. We didn't need an "slow visualisation" mode.

The computer was slow by itself, so it was just natural to see the Logo turtle move, stop, rotate, stop, and draw a line.

Areas were filled in the most naive of the ways: pixel by pixel, from left to right, line by line from top to bottom.

That unavoidable delay between instructions allowed us to "internalise" what was going on. Surely, it was slow, but it taught you how programming worked.

Casually, and a great proof of why Bret is right, I didn't like BASIC. It wasn't visual. I tried to go through the BASIC manual and it was a bore. Registers? File access? Input, output? Give me lines and points and allow me to draw. Also, I couldn't abstract things with BASIC, just as I could teach Logo to do things, with the to keyword:

In BASIC you had "subroutines" via the use of the GOSUB keyword. It was ugly and horrible to follow:


10 GOTO 40
20 PRINT "HELLO"
30 RETURN
40 GOSUB 20
50 PRINT "WORLD"

Logo was intuitive. No line numbers, no nonsense, and fun!

I later tried a Logo interpreter that run on an AT machine, at 12MHz. I taught it the usual square trick, and it was so fast in comparison, that the square instantly appeared on screen. Somehow, part of the fun was lost.

Maybe much of the people refusing to accept Bret's suggestions (because they would "dumb down" programming) were taught in 80s, with slow computers, and have already internalised so many things that they can't put themselves in the place of younger wanna-be-programmers.

It's even worse when this sort of people are the ones designing programming courses, since they believe that everyone can visualise computers workflow as easily as they do. Hint: they don't.

Finally, Bret's idea of taking pieces of somebody else's code and sticking them in other pieces? Code-collages? That just brought to my mind the work of fhtr. I want that to happen, with generative stuff. Just imagine the possibilities!

Now to Sean's response.

I like the classification he makes between Humble and Arrogant responses, and how he gravitates between both, until settling for something in the middle, and recognising both sides have its weaknesses and advantages.

But oh, the irony! I had been browsing through Bret's website prior to reading Sean's article, and I found him verging on the arrogant side. Which is what often happens when you're a brilliant genius--you can't avoid being "arrogant", even if politely. NOTE: I'm not talking about me, I am just remarking that people that really know what they are doing aren't normally smooth, fluffy and tactful when it comes to giving their opinion on topics that matter to them. And an example is worth more than a thousand notes: Linus Torvalds.

Personally my vote goes for the "I don't quite know how this could work but I'd like to see exploratory work done on this domain" school of thought. My grey matter is too precious to waste it in futile matters such as attempting to mentally visualise stuff the computer could paint for me or deciphering what parameters mean.

A proof that this is desperately needed is just in front of me: a notebook, where I sketch what I want to draw in the screen before actually programming any of it. Because coding is such a long and occasionally cumbersome process that it can totally break the creative flow. You stumble on a simple thing --how do I change the colour or the line thickness or...?-- and when you're back with the solution, you have already forgotten what you wanted to draw. For me, it's not that I can't visualise things, but that I can't hold it all at the same time on my mind.

And while those awesome flow analysis tools and visualisations are developed and released to the world, I propose that we start turning what we have into something a little more intuitive and readable.

For example:

Let's use keyword parameters where possible. You can already do this with languages such as Python, Ruby, or Objective C. They might not have the hovering labels Bret mentions, but they are a start, and way better than a list of numbers with no obvious meaning:

What is more legible?


# this?
drawRectangle(100, 100, 100, 100)

# or this?
drawRectangle(x = 100, y = 100, width = 100, height = 100)

Let's pay attention to naming. If a method does something, it should be named after a verb that corresponds to what it does. If it returns something, without side effects, it should be named in a simple way (e.g. get*). Make things as evident and as self explanative as you can. And in case of doubt, discuss it with someone else.

Let's make things as decoupled as possible. Or in other words, avoid global state as much as possible. When things are really delimited, it's easy to hold them in your mind while you look at what is going wrong, and hence they are easier to debug. Having a look at functional languages might give you great insight on this, even if you don't go and migrate all your codebase to be purely functional.

Also, let's pay attention to the aesthetics of our code. Lack of white space, lack of indentation or lack of uniform indentation transmit a powerful message to the readers: whoever programmed this didn't really care about it. Really good code looks beautiful and hence it's easier to understand, or at least to try to: you want to look at it, because it's nice.

Do you remember how our beloved and ever missed _why explained how the arguments and parentheses worked together?

Think of it as an inner tube the method is pulling along, containing its extra instructions. The parentheses form the wet, round edges of the inner tube. The commas are the feet of each argument, sticking over the edge. The last argument has its feet tucked under so they don’t show.
#

Fun fact: he also added "extra" white space between the arguments and the parentheses:


front_door.paint( 3, :red ).dry( 30 ).close()

Let's pay attention to the structure of the project. This is hardly mentioned in software literature, but it's important for so many reasons. When I have a look at somebody else's project and all I see when I open its directory is a myriad of files and folders and stuff, and I don't know where to start, I fear for the worst. If they can't get files organised, how will the rest of the code be?

I think all projects should be organised in a way that it's dead obvious how to start with them. Not only because it makes it easier for other people to work on your project, but because it's easy for you to pick it up again, months later, without having to figure it out again from start.

I would suggest having something like the following (ignore entries that wouldn't apply to your project):


/build - a compiled version of your library/app
/docs - possibly in .txt so no compiling is needed in order to read them
/examples - demos of your library or sample files
/src
    /data - assets you need
    /libs - libraries you depend on
    /in as many folders as needed - your own code
    main entry file (e.g. main.cpp, index.html)
/tests
/utils - utilities for building and stuff
LICENSE
README
.gitignore (or similar)

If I was given a copy of a project with this structure, I would first have a look at the README file, use whatever information it provided me and then would try to run the project by going into src. Because the copy already included all the data and libraries, I wouldn't need to hunt for them somewhere else.

Some of these suggestions might be a bit too specific, whereas Bret was a lot more open-ended. But hey, I'm a practical person. And on that matter, something that annoys me in a way about Bret and his demonstrations is that he's always showing awesome interfaces but never releasing them! The curious in me wants to look at the code and understand which sort of magic is making everything happen, but he won't let me! T_T

And to conclude with an slightly unrelated topic, I love seeing this sort of public debate happening in personal websites and blogs again. Love, love, love it! <3