# Re: [stack] Whither Joy? Documentation

## wtanksleyjr@cox.net — 2003-01-17 16:06:22

    From: Manfred von Thun <phimvt@...>

     >I have no teaching duties for the first half of the

    >year, so I'll have some time to spend on possibly

    >several Joy projects.

     Excellent!

     >Also, Billy: As far as I can tell the term

    >"concatenative notation" or "concatenative language"

    >first occurred in the name of this mailing group.

    >So am I right in believing that I should attribute

    >it to you ?

     You know, I thought you had used it first. But looking

    over your pages, I don't see that -- all I see is you

    mentioning concatenation as primary syntax. I definitely

    took all inspiration for the title from your descriptions.

    So, as far as I know, I guess I *was* the first to use it

    that way. Unless someone else remembers telling me...

     >Best of 2003 to all.

     Thank you -- and to you too.

     >   - Manfred

     -Billy

## phimvt@lurac.latrobe.edu.au — 2003-02-13 04:51:07

    I have updated the "Tutorial" paper, but not all that much.

    Most of it concerned John Cowan's floats, and there is

    only a brief mention of files.

    My next project is to update the "Implementation" paper, which

    is terribly out of date. There will be quite a lot to be done there,

    including on John's garbage collector, and how to install Joy.

    I will need some help from Nick with the documentation for

    command line arguments. I envisage that this part of the

    documentation will be in a section "Running Joy",

    which might start as:

      1. In the simplest case the Joy interpreter can be run

         from a command line which will typically just be

              $   joy

         This will invoke the Joy interpreter using the

         keybord and the screen for input and output.

         The interpreter will then announce itself

         ...

         [This is straighforward]

      2. Under unix and some other OS input and output can

         be redirected to come from a file or to go to a file:

              $   joy  <myinput  >myoutput

         ...

         [This is easy, too]

      3. Another possibility is to give command line parameters:

              $   joy  ...

         ...

         [Nick, here you have more experience than I, and you

          wrote the code, too. Would you have the time to write

          an appropriate paragraph or two, please ?]

      - Manfred

## Nick Forde — 2003-02-15 12:01:51

    phimvt@... writes:

      >      [Nick, here you have more experience than I, and you

     >       wrote the code, too. Would you have the time to write

     >       an appropriate paragraph or two, please ?]

     Sure. I'll get back to you with this as soon as I get a little free time.

    Regards,

    Nick.

## phimvt@lurac.latrobe.edu.au — 2003-04-10 07:24:31

    On Sat, 15 Feb 2003, Nick Forde wrote:

     > phimvt@... writes:

    >  >      [Nick, here you have more experience than I, and you

    >  >       wrote the code, too. Would you have the time to write

    >  >       an appropriate paragraph or two, please ?]

    >

    > Sure. I'll get back to you with this as soon as I get a little free time.

     I have now rewritten Paper 9: "The current implementation" on

    the main Joy page. There is a section Sec 5: "Initiating a Joy session"

    on how to run Joy, with just terminal IO, or with redirected IO,

    or with the command line argument as you implemented it (and as I

    understand it). Would yu please have a look at it? Thanks.

    My next plan is to rewrite some of the long forgotten

    "typlib.joy" as several very simple module libraries - just

    to get the hang of it.

    Greetings to all - we all seem to be busier than usual.

      - Manfred

## Nick Forde — 2003-04-14 12:14:48

    phimvt@... writes:

      >

     > On Sat, 15 Feb 2003, Nick Forde wrote:

     >

     > > phimvt@... writes:

     > >  >      [Nick, here you have more experience than I, and you

     > >  >       wrote the code, too. Would you have the time to write

     > >  >       an appropriate paragraph or two, please ?]

     > >

     > > Sure. I'll get back to you with this as soon as I get a little free time.

     >

     > I have now rewritten Paper 9: "The current implementation" on

     > the main Joy page. There is a section Sec 5: "Initiating a Joy session"

     > on how to run Joy, with just terminal IO, or with redirected IO,

     > or with the command line argument as you implemented it (and as I

     > understand it). Would yu please have a look at it? Thanks.

     Manfred,

    It looks OK to me. You might also want to mention that executable

    shell scripts can be created on Unix by prefixing joy source files

    with a reference to the joy executable, e.g. #!/usr/local/bin/joy

    This means programs can be run directly on the command line without the

    "joy" prefix. For example, saving the following in the file "ackermann":

    ----------------------------------

    #!/usr/local/bin/joy

    # ackermann - ackermann's function

    DEFINE M   == [argc 1 >] [argv second 10 strtol] [1] ifte.

    DEFINE N   == [argc 2 >] [argv third  10 strtol] [1] ifte.

    DEFINE res == "ack( " putchars M put ", " putchars N put ") = " putchars put "\n" putchars.

    DEFINE ack == (* I:n I:m -> I:a *)

      [

        [ [0 =] [pop 1 +] ]

        [ [swap 0 =] [popd 1 - 1 swap] [] ]

        [ [dup rollup [1 -] dip] [swap 1 - ack] ]

      ] condlinrec .

    N M ack res .

    ----------------------------------

    and then setting the executable flag using "chmod +x ackermann". The

    program can be run as:

    $ ackermann 2 3

    ack( 2 , 3 ) = 9

    Regards,

    Nick.

## phimvt@lurac.latrobe.edu.au — 2003-04-17 06:37:56

    > On Mon, 14 Apr 2003, Nick Forde wrote:

     [..about using command line arguments..]

    Amazing! Doubly amazing!

    1. I had used  "here document" tricks in Unix, but the technique

       of using #!progname in shell files was new to me. Amazing!

       Certainly my older books did not mention it. After some

       searching through the info page for bash I found it - cryptic

       as it is. But I concluded (probably wrongly) that this was

       Gnu bash specific, and that the doc for the Joy page should

       contain a warning to that effect. But now a guru friend tells

       me that it works under any shell (sh? csh? ksh?). Is this

       correct ?

    2. You Ackermann file and function is amazing, too. I had never

       thought that there might be cases where condlinrec could use

       an additional explicit recursion. Very clever indeed. I need

       to look at it more closely, though. The order of arguments

       for the file and the function are puzzling to me. Unless I

       quite misunderstand, the order for the command

          ackermann  m  n

       will be as in the standard texts, but for the Joy function

          m  n  ack

       it is reversed. (The reversal is cancelled by the definitions

       in your M and N.) Maybe you did this to increase the efficiency

       of ack? I'll look at it further.

    3. Whether Ackermann is a suitable example of a stand alone

       Joy program is another matter. Some users might not know about

       what Ackermann does, and might be puzzled by eternal execution

       times for even moderately large M and N. But I agree with you

       that an example should not rely on any Joy library. Perhaps

       the one-line non-recursive version of quicksort will be

       simple, easy to understand and even marginally useful.

    4. But I am glad you re-kindled my interest in the Ackermann function.

       I had pushed it aside because (a) it seems to be just a curiosity,

       and (b) it has a strange recursion pattern that is so complex

       and (c) this pattern does not occur elsewhere. Because of (b)

       I never bothered about an "Ackermann-recurse" combinator along

       the lines of linrec, tailrec and binrec. But reading last night,

       I am no longer so sure about (b). More about that some other time.

    Thank you very much.

      - Manfred

## John Cowan — 2003-04-17 11:55:58

    phimvt@... scripsit:

     > 1. I had used  "here document" tricks in Unix, but the technique

    >    of using #!progname in shell files was new to me. Amazing!

    >    Certainly my older books did not mention it. After some

    >    searching through the info page for bash I found it - cryptic

    >    as it is. But I concluded (probably wrongly) that this was

    >    Gnu bash specific, and that the doc for the Joy page should

    >    contain a warning to that effect. But now a guru friend tells

    >    me that it works under any shell (sh? csh? ksh?). Is this

    >    correct ?

     For the last 10-15 years this feature has been implemented directly by

    the kernel: when it opens a program for execution, it checks the first

    two bytes, and if they are "#!", the program named on the rest of the

    first line is run and passed the original program as an argument.

    A single additional argument may be specified on the first line, in

    which case the name of the original program becomes a second argument;

    for example, to run awk programs one must begin them with "#!/bin/awk -f",

    and it is conventional to begin Perl programs with "#!/usr/bin/perl -w"

    to enable all warnings.

    In the last five years, most kernels have left the file open on file

    descriptor 3 and then passed /dev/fd/3 (or the local equivalent) to

    the named program rather than the original filename.  This prevents a

    security loophole whereby a bad guy replaces the original program just

    after the kernel does permission checks.  This change is transparent to all

    non-perverse programs.

    Historically, sh intercepted "bad executable format" errors and ran the

    file with a forked copy of itself, and csh implemented the #! convention.

    But all that has been moot for ages.  Since the work is being done in

    the kernel, it does not matter what shell you use.

    The existence of this convention provides pressure for all programs

    that interpret their commands to understand "#" as the start of

    comment, at least in initial position.  Luckily, Joy already does so.

    For interpreters that do, the distinction between interpreted and compiled

    programs becomes insignificant for the user (other than in run time,

    of course).

    Here's a nice hack: start a text file with "#!/bin/sed 1d" and then

    chmod it executable.  Running the file will cause it to display itself

    (sans first line) to the terminal.

    --

    John Cowan                              jcowan@...

    http://www.ccil.org/~cowan              http://www.reutershealth.com

    Thor Heyerdahl recounts his attempt to prove Rudyard Kipling's theory

    that the mongoose first came to India on a raft from Polynesia.

            --blurb for _Rikki-Kon-Tiki-Tavi_

## Samuel Falvo — 2003-04-17 15:18:37

    > A single additional argument may be specified on the first line, in

     At least under Linux and BSD, I believe that you are not restricted to a single

    argument.

    --

    Samuel A. Falvo II

    __________________________________________________

    Do you Yahoo!?

    The New Yahoo! Search - Faster. Easier. Bingo

    http://search.yahoo.com

## Samuel Falvo — 2003-04-17 15:09:09

    > 1. I had used  "here document" tricks in Unix, but the technique

    >    of using #!progname in shell files was new to me. Amazing!

    >    Certainly my older books did not mention it. After some

    >    searching through the info page for bash I found it - cryptic

    >    as it is. But I concluded (probably wrongly) that this was

    >    Gnu bash specific, and that the doc for the Joy page should

    >    contain a warning to that effect. But now a guru friend tells

    >    me that it works under any shell (sh? csh? ksh?). Is this

    >    correct ?

     Correct; #! syntax is standard Unix fare, for all Unices.  It was introduced

    because of the extreme configurability of Unix.  User A might be using csh for

    his shell, while user B might be using plain old sh (not necessarily Bash).  In

    order to let a shell script written for sh be executable by someone using csh,

    some mechanism needed to be adopted whereby the shell knew what program to use

    to interpret the script.  #! is the result.

     >    will be as in the standard texts, but for the Joy function

    >       m  n  ack

    >    it is reversed. (The reversal is cancelled by the definitions

    >    in your M and N.) Maybe you did this to increase the efficiency

    >    of ack? I'll look at it further.

     At least in Forth, it's often the case that stack items are reversed from what

    the reader will expect them to be.  That is,

      a / b

    isn't always mapped directly to:

      b a /

    In fact, in Forth, the order is actually thus:

      a b /

    Sometimes this has to do with efficiency.  However, most of the time, it has to

    do with program readability for the human reader.

    More often than not, if you do find a strict reversal of parameters on the

    stack, it's almost always for efficiency purposes.  :)

    --

    Samuel A. Falvo II

    __________________________________________________

    Do you Yahoo!?

    The New Yahoo! Search - Faster. Easier. Bingo

    http://search.yahoo.com

## John Cowan — 2003-04-17 18:29:17

    Samuel Falvo scripsit:

     > At least under Linux and BSD, I believe that you are not restricted to a single

    > argument.

     But under Solaris and other System-V-ish Unixes you are.

    --

    John Cowan  <jcowan@...>  http://www.ccil.org/~cowan

            Raffiniert ist der Herrgott, aber boshaft ist er nicht.

                    --Albert Einstein

## Nick Forde — 2003-04-18 11:57:31

    phimvt@... writes:

      > 2. You Ackermann file and function is amazing, too. I had never

     >    thought that there might be cases where condlinrec could use

     >    an additional explicit recursion. Very clever indeed. I need

     >    to look at it more closely, though.

     >[...]

     I included the Ackermann implementation in my email because it was the

    only program I had to hand which used 'argv'. I agree that it's not a

    good example for the Joy documentation. I wrote this some time ago but

    as you've commented on it I have a few observations and questions.

    To write this function I began with the following definition:

      1. If x = 0 then  A(x, y) = y + 1

      2. If y = 0 then  A(x, y) = A(x-1, 1)

      3. Otherwise,     A(x, y) = A(x-1, A(x, y-1))

    Translating this directly into Joy led me to:

    DEFINE ack0 == (* I:y I:x -> I:a *)

      [0 =]                         # if (x == 0)

      [pop 1 +]                     # return y + 1

      [

        [swap 0 =]                  # if (y == 0)

        [popd 1 - 1 swap ack0]      # A(x - 1, 1)

        [

          dup rollup [1 -] dip ack0 # A(x, y - 1)

          swap 1 - ack0             # A(x - 1, ack(x, y - 1)

        ] ifte

      ] ifte.

    When I first looked at the Joy recursive combinators my initial

    feeling was that they belonged in a compiler and not in user

    code. Whilst I recognised tailrec, linrec, & binrec, etc. as common

    patterns, applicable in any recursive language, I wasn't so sure

    asking the user to explicitly identify them was a good thing. I've

    since changed my mind but would be interested in what others on the

    list think.

    Having written the ack0 implementation above I decided that use of a

    recursive combinator would be appropriate to improve performance and

    make the definition less verbose. This made me look more closely at

    the structure of the function and I quickly realised that it didn't

    follow one of the common (simple) patterns with which I was

    familiar. The closest of the available Joy combinators (condlinrec)

    also didn't quite cut it but I did come up with the following:

    DEFINE ack1 ==

      [

        [ [0 =] [pop 1 +] ]

        [ [swap 0 =] [popd 1 - 1 swap] [] ]

        [ [dup rollup [1 -] dip ack1 swap 1 -] [] ]

      ] condlinrec.

    This was a slight improvement over ack0 but it's ugly and I wasn't

    happy that the recursive ack1 call was so well hidden. This led me to

    rearrange as:

    DEFINE ack2 ==

      [

        [ [0 =] [pop 1 +] ]

        [ [swap 0 =] [popd 1 - 1 swap] [] ]

        [ [dup rollup [1 -] dip] [swap 1 - ack2] ]

      ] condlinrec.

    At least now condlinrec looks like a better fit and the explicit call

    to ack2 is prominent.

    So why did this exercise turn me in favour of the explicit recursive

    combinators in Joy?

    In recent years I've found the "Gang of Four" Design Patterns book

    (http://hillside.net/patterns/DPBook/DPBook.html) to be useful for

    discussing programming problems with colleagues. For me the book's

    main benefit is that it provides a common lanugage for discussing

    patterns recognised by all experienced OO programmers. However I also

    find it is a useful checklist to go through when trying to decide on

    the most appropriate solution to a problem.

    On a smaller scale I think the Joy recursive combinators offer similar

    benefit in that they make the programmer consider whether their

    function follows one of the common recursive implementation patterns

    (the checklist). Identifying explicit recursive patterns in this way

    also gives an indication of a function's form which other programmers

    can readily follow (the common language).

    So what do you think? Are these combinators a good thing?

    Manfred, what led you to select the recursive combinators in Joy? Were

    these taken directly from established recursion theory? Can you

    provide any references?

    Regards,

    Nick.