Sunday, November 29, 2009

The J programming language

Today I went through the first few tutorials of the J programming language. J is a treat. The human language has many devices that keep things short and explicit. While in context-oriented programming people are still wondering how to properly identify and model the "context" of a statement, natural language already goes and changes the behaviour of nouns by specifying them more precisely with adjectives. Compare that with modern object-oriented programming languages, which only have nouns (classes) and verbs (methods) at best.

The J language tries to harness the power of the natural languages by providing nouns, verbs, adverbs, conjunctions, and comparatives. I'd love to see an OO version with adjectives.

The tutorials are splendid and the IDE helpful, which I won't elaborate on because James Hague wrote such a nice piece about the fact. Oh, and he raves about the built-in plotting. Here's some turtle geometry, similar to an example that they provide:

The source code was:
show repeat 20;'point (n =: n+1) fd 1 rt 15'[n=: _2
to 'goreturn a b';'goto b goto a'
to 'goreturnall a'; 'goreturn for a,.i.20'
show goreturnall for i.20

The article is over. Just one last thing: There's a funny glitch in the tutorials. The tutorials assume that you have some familiarity with Hilbert matrices and alternating binomial coefficients. But you are not expected to know how to handle a mouse:
The color window can be moved away from text that it may obscure by clicking on the top bar, holding the button down, and dragging it to a new position before releasing the mouse button –– Chapter 2, lesson 2 in the J tutorial


  1. If your OOP language has a decent metaobject protocol, it actually provides adjectives, or that's one way how to look at metaclasses. For example, in CLOS using its MOP, you can say the following:

    (defclass person ()
       ((name :reader person-name)
        (address :reader person-address))
       (:metaclass persistent-class))

    Given that somebody provided a suitable implementation of the metaclass persistent-class, you thus have specified your class person to be persistent (which is indeed an adjective!).

    Smalltalk's MOP is not well enough thought out to support these things, because there every class gets its own metaclass by default. This means that in Smalltalk, you cannot (easily) use metaclasses as an abstraction mechanism. However, in CLOS-style metaobject protocols, this is relatively straightforward and commonly used.

  2. Smalltalk has traits, which go into the same direction. The typical thing for an adjective to do is to refer to a quality in the noun and use it to define a new quality. For example, the word "good" means "good at fulfilling its purpose." For example, a good school and a good wife may have very different qualities.

    Where traits fail is in reifying the new aggregation. In Smalltalk, you can make a new School class and have it use the "good" trait. But that will change ALL schools.

  3. So what about having a subclass of school that is good-school?

  4. Well, then we're back to our noun-only world :).
    Adjectives should be generic enough to modify a range of nouns. Compunds of adjectives and nouns should be used everywhere where a noun can be used. But they are not themselves new nouns, because the number of possible combinations of adjectives that you can associate with a word is large. Also, it should be possible to add adjectives to a noun after it was first discussed. As in the small dialog:

    A: I went to school in Ludwigsburg.
    B: Was it a good school?
    A: It was excellent!

    Late-bound traits ftw :)

  5. There are a couple of possible answers to this. One is: Don't worry, be happy. ;) A better answer may be CLOS's change-class, which indeed allows you to add new mixins/traits/superclasses/whatever you want to call them on the fly. Or you implement them as plain states, as in school.quality = good. ;) Now a problem with modeling such information as state is that you normally cannot dispatch on it. However, there is an answer to that as well. See (and that may actually be a step closer to providing a context-oriented solution or this problem...).

    It remains that what you essentially need is a good metaobject protocol, in order to implement such variations of OOP.

  6. Well, of course an adjective is more than a property, as it interacts with the noun similar to the way traits interact with the containing class. I'd really enjoy an adjective language, perhaps like this:

    house := Factory buildHouse.
    house is: stable.

    Imho, the PL world makes a mistake when they demand re-use of verbs to follow a chain of inheritence. I'll give an example.

    In natural language, the verb "to tie " requires an object of one primary dimension. You can't, for example, use it on a frog, because a frog has three primary dimensions. What I want to say is that natural language has already sorted out which way of categorizations humans actually care about and which we don't. In natural language, the role of dimensions plays an important role, while most languages don't give it any thought.

    The concept of dimensionality is parallel to the concept of inheritance.

    People call J "mindbending," but despite all its problems, its use of ranks feels easy to me. And I just wonder: if dimensionalityis a natural way of people to think about the world, why should we completely ignore it in language design?

    Similarly: if everyone day in and day ought qualifies nouns by adjectives which interact with the noun, why not copy this evolved design into PLs?

  7. This comment has been removed by the author.

  8. Interesting... and yes mind blowing to read loopless code..! Smalltalk can allow greater experimentation than other mainstream languages, in a constrained manner though.

    Language though will be widely used only as much as the need exists for its features. The more academic it becomes, discernible to the very few, the lesser its adoption, despite all its power or elegance.

    For terseness i guess is really nice to have, idioms that can become comprehensible over time:

    Why not tinker a bit with parsing custom grammar in PetitParser to achieve what is shown...
    0 100 + i. 2 3 probably as..

    #{0 100 + i. 2 3} to return a Matrix instance that prints literal matrices

    #{ 1 6 3 6 7 < 3 } that results in a collection #select: ecquivalent..

    for boolean eval: guess needs no more than a #andIf:else: / #orIf:else: methods in Collection

    { boolExprBlock1 . boolExprBlock2 . boolExprBlock3 }
    andIf: exprBlockA else: exprBlockB

    remove the complexities of and: [ ] / or: [ ] , brackets et al..


Note: Only a member of this blog may post a comment.