I'm James Hague, a recovering programmer who has been designing video games since the 1980s. Programming Without Being Obsessed With Programming and Organizational Skills Beat Algorithmic Wizardry are good starting points. For the older stuff, try the 2012 Retrospective.
Where are the comments?
Follow-up to "A Programming Idiom You've Never Heard Of"
Lots of mail, lots of online discussion about A Programming Idiom You've Never Heard Of, so I wanted to clarify a few things.
What I was trying to do was get across the unexpected strangeness of function inverses in a programming language. In that short definition of vector magnitude, there wasn't a visible square root function. There was only an operator for squaring a value, and another operator that involved inverting a function.
How does the J interpreter manage to determine a function inverse at runtime? For many primitives, there's an associated inverse. The inverse of add is subtract. The inverse of increment is decrement. For some primitives there isn't a true, mathematical inverse, but a counterpart that's often useful. That's why the preferred term in J isn't inverse, but obverse.
For user-defined functions, there's an attempt at inversion (er, obversion) that works much of the time. A function that reverses a list then adds five to each element turns into a function that subtracts five from each element then reverses the list. For cases where the automated obverse doesn't work, or where you want the obverse to have different behavior, you can associate a user-defined obverse with any verb (J lingo for function). You could define an
open_file verb which opens a file and has an obverse that closes a file. Or in actual J:
open_file =: open :. close
Well, really, that should be:
open_file =: (1!:21) :. (1!:22)
But the former, without the explicit foreign function calls, gets the point across clearer, I think.
One common use of obverses and the "under" operator is for boxing and unboxing values. In J, a list contains values of the same type. There's no mixing of integers and strings like Lisp or Python. Instead you can "box" a value, then have a list containing only boxed values. But there's nothing you can do with a boxed value except unbox it, so it's common to say "[some operation] under open box," like "increment under open box." That means unbox the value, increment it, then put it back in a box. Or in real, eyeball-melting J:
inc_box =: >: &. >
>: is increment. The right
> means open box. That's the "under" operation in the middle.
Now it sounds like this "open box, do something, close box" sequence would translate beautifully to the "open file, read the contents, close the file" example I gave last time, but it doesn't. The catch is that the open / read / close verbs aren't manipulating a single input the way
inc_box is. Opening a file returns a handle, which gets passed to
read. But reading a file returns the contents of the file, which is not something that can be operated on by
close. So this definition won't work:
read_file =: read &. open
If a structured data type like a dictionary was being passed around, then okay, but that's not a pretty example like I hoped it would be.
Still, I encourage learning J, if only to make every other language seem easy.
permalink January 5, 2012
previouslyA Programming Idiom You've Never Heard Of
User Experience Intrusions in iOS 5
Photography as a Non-Technical Hobby
Adventures in Unfiltered Global Publishing