# Comments - 10

## phimvt@lurac.latrobe.edu.au — 2000-08-10 02:59:55

    Hi folks - I seem to be getting there, albeit slowly. Manfred

    1. "function quotation or voracious evaluations"

        Stevan Apter (26-JUN-2000) wrote of voracious evaluation.

    I had been thinking about that some time ago. But I dropped it because

    I could not think of any good use for it. The idea is that programs

    write programs that write programs ... until there isn't anything left

    to execute them.

        One simple version:

              [..some-program..] i i i ... i    until it is pointless

        Another version (using the stack instead of the top quotation):

              start with empty stack, execute a program that leaves a stack

              WHILE the stack is a program DO

                 (perhaps reverse the stack and then)

                 execute the stack

        Example of the second version:

                [+] first 3 2

                leaves a stack with + at bottom, then 3, then 2 on top.

                this is the same as the quotation [2 3 +]

                it can be executed again to finally give 5

            No doubt such a repeated executor can be written in Joy.

    But I still cannot think of any real uses of that sort of thing,

    apart from the (one-step) constructed programs that Joy uses a lot.

    Can anyone think of real uses of two-step constructed programs?

    Any ideas in general?

    2. "generalised stack operations"

        Stevan also introduced some neat generalisations of the

    stack operators. For example "ndup" expects a number n and below

    that at least n further items. It then duplicates the n-th item.

    Then he defines  dup ==  1 dup. He suggests the generalisations

    as new primitives.

        I think we need to be clear on several notions here. One is

    the view that the (short and lean) list of primitives is a logical

    minmimum, from which the rest can be built. Another is that the

    primitives are a good psychological base from which to define

    the rest. A third is that the primitives are implemented directly,

    and that everything else is in a library. [Compare all this with

    the operations in Boolean algebra, and a good collection of

    primitives in the three senses.]

        Any thought on this?

    3. "Three more proposals about Joy"

         This started off with 3 proposals by Brent Kirby, and there was

    a lot of interesting discussion about each of them and some others.

         (1) 'Feel free to pile onto the stack'. I think this idea must

    have its source in (what I take to be) an APL idea:

               1 2 3 + 4 5 6

           ==> 5 7 9

    It works well with infix notation for binary operators, but with postfix

    there is a problem. How is one to compute one list, compute another list

    and then concatenate them, for example?  Or, taking the example above,

    how is one to distinguish the first array 1 2 3 from the second 4 5 6 ?

    I cannot see a way out.

         (2) 'Eliminate inspection of quotations'. There are two reasons

    why one might want to _forbid_ it: (a) the processor has optimised the

    code in the quotation, so that it is no longer what the programmer

    wrote. But in that case  the processor will just have to leave two

    versions available - one for inspection, the other for (fast) execution.

    (b) quotation is opaque: even though e.g.  dup +  ==  2 *,

    [dup +] =/= [2 *], as may be seen by taking firsts or seconds on

    both sides. This objection could be handled by distinquishing

    function-body-quotations from list-quotations - e.g. by different

    parentheses. To preserve "constructed programs", they can be build up

    but not inspected. I am not sure whether all this is worth the trouble.

        (3) Stevan prososed what I think of as a shuffle pattern -

    a general device for rearranging the top few elements of the stack

    in a way that is nice, visible, and immmediately intelligible.

        (4) Louis Madon pointed out that in my prototype the program

              1  [pop]  nullary

    produces a coredump. It should produce an error instead. I think I

    know how to fix it - when I have time. Also, the Joy combinator

    "while" is unfortunately called "whiledo" in several of the papers.

    I like "whiledo" better since it suggests the two program parameters

    that are required. So I'll add "whiledo" as a duplicate, change

    the libraries, but continue to allow "while" as an alternative

    that is to be eliminated in the long run.

        (5) 'lambda'  -  I am not at all sure of this, but I got the

    distinct impression that what was described was not lambda abstraction

    (which introduce named formal parameters as in the lambda calculus),

    but local definitions of function symbols (concatenative, i.e.

    parameterless). Please correct me.

        (6) 'string comparison' (this was for conk). I would have

    thought that an obvious way to compare "abc" with "defgh" is to

    padd the shorter with nulls:  "abc.." < "abcd." < "abcde" < "defgh",

    where the period indicated the null, chr(0) or ASCII 0. That

    should be easy to implement, and it makes some sense. Then

    max and min and so on become sensible automatically. This is how

    it is done by C's  strcmp( , ). That is a general purpose function

    from which several comparison functions (and hence also max and min)

    can be defined.  Or did I miss something in the discussion?

        There is another chain of reasoning, though. Strings are just

    sequences of characters (_implemented_ in whatever way: as the content

    of sequences of memory locations, i.e. as arrays, OR as linked lists).

    Vectors in general are much the same, except that the contents do not

    have to be characters, they can be other numbers or anything.

        If it is a good idea to pad strings with nulls for comparisons,

    then perhaps it is also a good idea to pad vectors of say numbers

    with the appropriate unit element of binary operations, say 0 for

    addition, 1 for multiplication.  For example, to add the two vectors

    (1 2) and (3 4 5) which are of unequal length, we think of adding

    a trailing 0 to the first, to give (1 2 0). Then (1 2)+ (3 4 5)  =

    (4 6 5). Call this the "naive consistency requirement". Is it a good

    idea?

         One might argue that it eliminates many (compile- or run-time)

    errors that could be annoying when developing programs. On the other

    hand one might argue that an explicit error message, preferably at

    compile-time, but at least at run-time, is better than a running

    program that produces strange results. My preference is normally

    for strong typing (yes, I know, I know, what about Joy ...).

         I do not know what Forth and APL/J/K do with the example. But

    it is a consideration relevant to the popular view that strings

    are just vectors of numbers.

         [Rather incidentally, Joy uses strcmp( , ), and hence pretends

    null padding. Hence you can sort lists of strings of different lengths:

            ["Cassandra" "Di" "Bob" "Anastasia"]  qsort   ==

            ["Anastasia" "Bob" "Cassandra" "Di"]

    as expected. On the other hand, zip does not do any padding because

    there is no appopriate unit element, so zip produces a list of pairs

    no longer than the shorter of the two parameter lists. It might be

    worth going through Joy with a fine comb in search of cases where

    there are suitable unit elements.]

    4. "The Josephus problem" - I read it and was impressed by the

    code given. But I cannot really comment on it.

        Well - this catching up took a long time

            Manfred

    P.S. Zeno has been at it again - more concatenative mail on

        "Another implementation of Joy"  -  I'll study that, but now now.