Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Notation as a Tool of Thought (1979) [pdf] (toronto.edu)
58 points by brudgers on Oct 1, 2014 | hide | past | favorite | 12 comments


See also: http://www.jsoftware.com/papers/DFSP.htm - impressive practical application of this notation. I've never seen a more succinct (yet still rigorous to the point of being executable) description of the Simplex algorithm, which is given as an example here.

I wish more people were familiar with Iverson's work (APL, J) and its descendents (mostly K). Everything else is so needlessly complex in comparison.

There is a steep learning curve, true - but it is well worth it.


I'm still on the far low end of the curve, but APL (I prefer APL due to its non-ASCIIness) has quite a beauty in it. For "play" I wrote a sample for a normal distribution (using Box-Müller, since it was simpler than other, faster algorithms.) Here's the code (u is a function returning a sample from a uniform between 0 and 1, so just calling u is a random number in [0,1]). The only non-self evident bits would be →(s≥1)/ (which means if s greater than 1, jump to whatever label is after the slash) and ⍟var which is Pi times var. APL is really neat, and this is not even an example of a nice, array-oriented algorithm.

  ∇a←norm;uu;vv;s
    ⍝ Normal distribution around 0 (using the Box-Muller transform in polar form
    ⍝ Local variables go in the header after semicolons
    CHOOSE: 
    uu←u
    vv←u
    s←(uu * 2)+vv * 2
    →(s≥1)/CHOOSE
    →(s=0)/CHOOSE
    m←(((¯2×⍟s)÷s) * 0.5)
    a←uu×m
  ∇
Edit: forgot to format


Other things that are non-self-evident except to people already familiar with APL: * means exponentiation, not multiplication; and "⍟var which is Pi times var" is incorrect: it's actually log(var).

I have to confess that I don't find this sort of example very compelling; Box-Muller isn't much more than a one-liner in any language. I mean, here it is in C, not noted for its richly expressive terseness:

  double norm(void) {
    while (1) {
      double u=rand01(), v=rand01();
      double s = u*u+v*v;
      if (0 < s && s <= 1) return u * sqrt(-2*log(s)/s);
    }
  }
(I assumed that we already had a rand01() function equivalent to your "u"; I suggest that in any nontrivial program the gain in brevity from the single-character name is outweighed by being unable to call a local variable "u" and, if you have a bunch of these, the cognitive load of remembering what all the single-character names mean.)

I bet the C implementation is distinctly easier to make sense of for most mathematicians and most programmers, and it's not even substantially longer. (APL: 94 non-blank characters. C: 111 non-blank characters. I remark that counting non-blank characters is about as favourable a metric for APL as one can reasonably ask for.) One can code-golf it further: combine the declaration of u,v with that of s (saves 5 non-blank characters --> 106); switch to your "u" instead of my "rand01" and rename u,v to (say) x,y (saves 10 characters --> 96); convert to do/while and use commas instead of {;;;} for body (saves 4 characters -> 92). That looks like this, and I think is still pretty easy to read:

  double norm(void) {
    double x,y,s;
    do x=u(), y=u(), s=x*x+y*y; while (s==0 || s>1);
    return x*sqrt(-2*log(s)/s);
  }
(Note: character-counting is by hand and it's entirely possible I'm out by a couple of chars either way.)

[EDITED to fix formatting screwage; aargh, I hate HN's treatment of asterisks]


You are right, π times is the monadic "circle" function... Still trying to learn fluently all operators. And indeed, it's not a specially good example, but I don't have a lot of APL code written (the "nicest" being a Mandelbrot set one-liner), the "longest" being this one and a function to generate histograms, but way harder to read, since it uses quite a few operators:

  ∇a←n hist x
    ⍝ Histogram data from x in n buckets
    s←x[⍋ x]
    mx←¯1 ↑ s
    mn←1 ↑ s
    bk←mn+(⍳n)×(mx-mn)÷n
    a←+/(~(↑bk)<s)
    s←((↑bk)<s)/s
    bk←1↓bk
    LOOP:→(0=⍴bk)/END
    a←a,+/(~(↑bk)<s)
    s←((↑bk)<s)/s
    bk←1↓bk
    →LOOP
    END:
  ∇
Not brilliant, and even at the time of writing (5 or 6 months ago) I had the feeling it may be possible to write it loopless or close enough. Variables in this one are still "global" since (even if it works) I was still checking it for possible bugs.


What interests me is the idea of using a larger character set to improve code readability [not readability in the lowest common denominator sense, nor in the high priest of Perl sense either]. Just in the sense of making conventions concise.

    💉foo()  // dependency injection
    🌏eggs   //  geospatial value
I'm not advocating standardization [ala APL at the language level]. I am thinking about making sections of code better diagramatically.


Iverson was a great man. His specialized notation that was the undercarriage of APL changed many people's view of programming because he forced a more mathematical and consistent use of array notation, far beyond the simple subroutine notations used in FORTRAN at the time.


APL buttons for your favorite UniComp/IBM buckling spring keyboard.

http://pckeyboard.com/page/Buttons/USAPLSET


My version: Choosing the right tool for the job is half the battle.


The ACM paywall is pretty horrible. How about a version that people can actually read:

http://www.eecg.toronto.edu/~jzhu/csc326/readings/iverson.pd...



It wasn't behind a paywall when I posted the link. Sorry about that. I should have known analytics would kick in their Nigerian Prince routines.

Of all the organizations that go out of their way to make the web suck, ACM is one of the few for which the choice of behavior is a tragedy..


Error: Access forbidden. (They're sorry though.)




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

Search: