# Re: [stack] Joy inbuilt editor [was RE: Inlining in Joy] (fwd)

## Manfred von Thun — 2001-05-03 06:58:08

    On Wed, 2 May 2001, John Cowan wrote:

     > Manfred von Thun wrote:

    >

    >

    > > What I said in an earlier posting about an inbuilt editor is relevant.

    > > One might (but it needs discussion whether it is worthwhile) do this:

    > >   1. Introduce a new datatype "stringbuffer" (= a string + a movable

    > >      integer pointer)

    >

    > This makes me nervous.  Hitherto, all Joy types have been immutable

    > values.  Now we are introducing a mutable object.  I would prefer to

    > keep mutability under the covers, and make things look immutable

    > to the user.  (I should have mentioned immutability before as

    > a Joy feature that makes distribution easy.)

     No need to be nervous. Nothing mutable here. It is just like, say,

    "rest":

       Stack before                Program              Stack after

       ... 1 2 3 [a b c]           rest                 ... 1 2 3 [b c]

    To give an example of a longish session with a fantasy Joy editor

    (Program written over many lines, "after" is on the next line):

       Stack                                    Program

       ... 1 2 3 "some tekst"                   edit

       ... 1 2 3 [1 "some tekst"]               6

       ... 1 2 3 [1 "some tekst"] 6             move

       ... 1 2 3 [7 "some tekst"]               2

       ... 1 2 3 [7 "some tekst"] 2             delete

       ... 1 2 3 [7 "some tet"]                 "x"

       ... 1 2 3 [7 "some tet"] "x"             insert

       ... 1 2 3 [7 "some text"]                finished

       ... 1 2 3 "some text"

    So, editing can be just as functional as the rest of Joy.

    But who would really want such a thing?

     > > (grown-ups like

    > > myself use TECO if they can get it to work in a new environment

    > > - never regretted it.)

    >

    > Hey, another TECO fan!  What TECO are you running on Linux these days?

     I started in 1978 on a DEC 10. Very fortunately somebody advised

    me to take the plunge and learn TECO rather than whatever other

    editor there was (SOS ?). In about 1980 we got a VAX running VMS

    (what, no more MIC ? but there were  .com  files ..), and, yes,

    there was TECO again.

    In 1987 or so I got an account on our Pyramid which ran Unix (Oh, no,

    it's so different from VMS). I started reading newsgroups there,

    but it did not have TECO. Then it appeared in comp.lang.sources

    as 4 shar archives: tec1.sh tec2.sh tec3.sh tec4.sh . I had no

    idea what a shar archive was, but I followed the instructions:

    "sh tec1" etc. Miraculously all sorts of files appeared on my

    directory. There was also the instruction to say "make". I did,

    not knowing what the hell that was supposed to do. Anyhow, it did

    not work, so I used vi to edit the files just a bit, then "make",

    and bingo, I had TECO on the pyramid. Since then I have ported

    that lot of files to a Sun under SunOS, and to a DEC alpha under

    unix. A few commands I just had to disable. This was my first brush

    with C. Recently the Sun on which I reside was made to run Linux,

    but I do so little there that I never bothered to get TECO up again.

    Most of my work is on a DEC alpha under VMS which has TECO anyhow.

    The 4 sh-sources incidentally were by Matt Fichtenbaum (c 1986).

    I believe they can still be found on the net, my early versions

    had been written for DEC Ultrix. An experienced C programmer should

    have no difficulty moving them to Linux.

    If anybody is wondering what TECO is:

    It is a complete, powerful string processing language. You can

    even write a compiler in it, even a self-compiling compiler

    which translates from a source language to TECO (get it?).

    See for example from my homepage the SYMBOLIC PROCESSING IN PASCAL

    page, or directly:

       http://www.latrobe.edu.au/www/philosphy/phimvt/s00bok.html

    and look at Chapter 21.

    Teco Users constitute a secret society. Its top ranks are

    High Priest, Seraphim, Cherumbim and Commissar. To join you

    need to have microchips with the TECO manual implanted in

    every fingertip (it hurts). You never have to think about

    editing again.

      - Manfred

## Dirk-Ulrich Heise — 2001-05-03 13:33:57

    -----Ursprüngliche Nachricht-----

    Von: "Manfred von Thun" <phimvt@...>

     > If anybody is wondering what TECO is:

    > It is a complete, powerful string processing language. You can

    > even write a compiler in it, even a self-compiling compiler

    > which translates from a source language to TECO (get it?).

     Sounds like fun. I'd love to see some bigger Joy program

    that does something useful. Would it be possible for one of

    you to implement a TECO-like thing in Joy? A string processing

    utility would be nice to crunch and manipulate source files.

    ( I won't tell you that i'm eager to translate it to Forth once

    it's there)

    Seriously: I'm lurking here to expand my horizon in the

    functional direction, and i already got two good ideas here:

    quoting programs with "["..."]", and the nifty "ifte" combinator.

    I don't have to tell you i re-implemented them in Forth, do i?

    Dirk Heise

    What's a life and where do i get one?

## John Cowan — 2001-05-03 13:43:43

    Manfred von Thun wrote:

     > Most of my work is on a DEC alpha under VMS which has TECO anyhow.

     Does the new Joy run on VMS/Alpha?

     > The 4 sh-sources incidentally were by Matt Fichtenbaum (c 1986).

     Yes, that's the one I use when I still use "te", but most of

    the time I use "ex" nowadays (the line-mode version of "vi").

    And people still think I'm a troglodyte.

     > Teco Users constitute a secret society. Its top ranks are

    > High Priest, Seraphim, Cherumbim and Commissar. To join you

    > need to have microchips with the TECO manual implanted in

    > every fingertip (it hurts). You never have to think about

    > editing again.

     Indeed, indeed.

    --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## Manfred von Thun — 2001-05-08 01:39:29

    On Thu, 3 May 2001, Dirk-Ulrich Heise wrote:

     > Von: "Manfred von Thun" <phimvt@...>

    > > If anybody is wondering what TECO is:

    > > It is a complete, powerful string processing language.

    >

    > Sounds like fun. I'd love to see some bigger Joy program

    > that does something useful. Would it be possible for one of

    > you to implement a TECO-like thing in Joy? A string processing

    > utility would be nice to crunch and manipulate source files.

     Here is a start:

    But I think it is better to store the editing buffer not as

    a pairlist  [p t], with integer pointer p and text t,

    but instead as just the pair  p t  on top of the stack:

        edit    ==  0 swap;

        move    ==  [swap] dip + swap;

        delete  ==  .. take ..   (* take string from start up to p *)

                    .. drop ..   (* drop string from start to p+n *)

                    concat;

    Maybe someone will do it properly..

    But let me repeat what I said earlier: is this really going to be useful?

     > ( I won't tell you that i'm eager to translate it to Forth once

    > it's there)

     There is this business of copyright ..

     > Seriously: I'm lurking here to expand my horizon in the

    > functional direction, and i already got two good ideas here:

    > quoting programs with "["..."]", and the nifty "ifte" combinator.

    > I don't have to tell you i re-implemented them in Forth, do i?

     I am sure the Forth programmers in this group would like to see

    how you do the quotation. If you can do that, then many of the

    others should not be too hard in Forth. But (no knowing Forth)

    as far as I know recursion is hard in Forth, and so would be

    any recursive combinator. Let us see what you have.

      - Manfred

## Manfred von Thun — 2001-05-08 02:28:13

    On Thu, 3 May 2001, John Cowan wrote:

     > Manfred von Thun wrote:

    >

    >

    > > Most of my work is on a DEC alpha under VMS which has TECO anyhow.

    >

    > Does the new Joy run on VMS/Alpha?

     I'm sorry, I havn't had the time yet, and won't for another week

    (busy written official answers for an assignment, writing the

    next assignment, marking a nasty little pile of assignments).

    I'll have to get your current .tar.gz on a Sun, telnet it over

    to VMS, and then see what happens.

     > > The 4 sh-sources incidentally were by Matt Fichtenbaum (c 1986).

    >

    > Yes, that's the one I use when I still use "te", but most of

    > the time I use "ex" nowadays (the line-mode version of "vi").

     What? "ex" ? Traitor !

     > And people still think I'm a troglodyte.

     Yes, I get remarks like that.

      - Manfred

## Billy Tanksley — 2001-05-08 18:29:58

    From: Manfred von Thun [mailto:phimvt@...]

     >On Thu, 3 May 2001, Dirk-Ulrich Heise wrote:

    >> ( I won't tell you that i'm eager to translate it to Forth once

    >> it's there)

    >There is this business of copyright ..

     You can only copyright expression, not ideas.  Once you release your idea

    it's fair game.

    Polite programmers, of course, will respect the author's wishes.

     >> Seriously: I'm lurking here to expand my horizon in the

    >> functional direction, and i already got two good ideas here:

    >> quoting programs with "["..."]", and the nifty "ifte" combinator.

    >> I don't have to tell you i re-implemented them in Forth, do i?

    >I am sure the Forth programmers in this group would like to see

    >how you do the quotation. If you can do that, then many of the

    >others should not be too hard in Forth.

     Quotation isn't hard in Forth, once you realise that quotation is actually

    building a data structure (i.e. it's not a magical syntactic operation).

    Forth has a datatype called an "xt", or "execution token"; an xt is what you

    use to execute a user-defined word.  To build a quotation, you'll have to

    build something similar to an array of xts.

    However, once you add quotations you have to add a couple more concepts:

     - should quotations have their own state?  That is, should IMMEDIATE words

    have effect inside of quotations, and if not, should there be a class of

    words which do?

     - should it be possible to build a quotation while inside a definition?

    These are hard questions; the only answers I've managed to find are

    militantly unForthlike.  My conclusion has been that Forth can't really use

    quotations, as such; it needs to use quotations as text strings.  Text

    strings have one problem: they can change meaning as words are redefined.

    The solution is Forthlike but requires a low-level compiler change: add

    'named fences' to the Forth dictionary which, when executed, force the

    dictionary search to start at the fence instead of at the top of the

    dictionary.  This way you can temporarily exclude future changes to the

    dictionary, so your text string will certainly execute as intended.

    This fits VERY well with Forth, since Forth gives such convenient access to

    the source code, for both inserting and deleting.  It doesn't match Joy very

    well, but frankly I don't care; Joy's solution is workable but odd.

    I don't share your admiration of ifte, by the way.  It looks good at first,

    but in reality it adds a LOT of difficulty, both in reading, writing, and

    compiling.  But then the entire concept of branching has its own

    difficulties :-).

     >But (no knowing Forth)

    >as far as I know recursion is hard in Forth, and so would be

    >any recursive combinator. Let us see what you have.

     Recursion is _trivial_ in Forth.  Simple recursion is handled by the word

    RECURSE, which calls the containing word (which does not have to be named).

    Backtracking is almost as trivial, although the standard doesn't officially

    support it, and it would be even easier with a way to return the current

    continuation.  I've posted a paper about it, which I can repost if it's

    needed.  It's a LOT simpler than most languages make it, and a LOT more

    powerful.

     >  - Manfred

     -Billy

## Manfred von Thun — 2001-05-10 08:31:48

    On Tue, 8 May 2001, Billy Tanksley wrote:

     > From: Manfred von Thun [mailto:phimvt@...]

    > >On Thu, 3 May 2001, Dirk-Ulrich Heise wrote:

    >

    > >> ( I won't tell you that i'm eager to translate it to Forth once

    > >> it's there)

    > >There is this business of copyright ..

    >

    > You can only copyright expression, not ideas.  Once you release your idea

    > it's fair game.

     Sorry, that was a joke about copyrighting an editor written in Joy. Sorry.

     > >> functional direction, and i already got two good ideas here:

    > >> quoting programs with "["..."]", and the nifty "ifte" combinator.

    > >> I don't have to tell you i re-implemented them in Forth, do i?

    > >I am sure the Forth programmers in this group would like to see

    > >how you do the quotation. If you can do that, then many of the

    > >others should not be too hard in Forth.

     [long reply by Billy]

     > I don't share your admiration of ifte, by the way.  It looks good at first,

    > but in reality it adds a LOT of difficulty, both in reading, writing, and

    > compiling.  But then the entire concept of branching has its own

    > difficulties :-).

     Do you mean just "ifte", or do you mean all combinators that have a test,

    like "whiledo" "linrec" "binrec" "treegenrec"? Or do you even mean all

    combinators?

    If you just mean "ifte", in an earlier version I had a simpler variant:

    compare "ifte" with "branch":

                  [ifpart] [thenpart] [elsepart]  ifte

                           [thenpart] [elsepart]  branch

    "branch" worked like this: if the top element of the stack is

    the Boolean value true, execute the thenpart, else execute the elsepart.

    (I take it this a little similar to Smalltalk's "iftrue" ??)

    The problem wit "branch" is that to get the required Boolean

    on top of the stack, some values are often going to get mangled

    when one wants them later for the ifpart or the thenpart.

    So the programmer has to ensure that below the Boolean all the

    values are retained. That can require awkward "reconstruction"

    at the front of the ifpart _and_ the thenpart.

    All this is circumvented by "ifte". The original stack is saved

    (it is just a pointer), the ifpart is executed and can mangle the

    stack as much as it likes, as long as it leaves a Boolean on top.

    Then that Boolean is inspected and the saved stack is re-installed

    (again, just a pointer). Depending on what the Boolean was, now

    the ifpart or the thenpart is executed. So "ifte" makes it easier

    on the programmer. I should add that in most programming languages

    executing a test does not have a side effect either. What I said

    about "ifte" also applies to the other combinators that have

    a test.

    "ifte" is easy to implement just in case the stack is a (linked)

    list. It would be much harder if the stack is a (consecutive memory)

    array  --  as in Forth. But one might well just have a "branch"

    instead, and leave the work to the programmer (I take it, with a

    few dups and saving on the return stack and later restoring).

    But surely some kind of branching or conditional execution is

    needed in _any_ language.

     > >But (not knowing Forth)

    > >as far as I know recursion is hard in Forth, and so would be

    > >any recursive combinator. Let us see what you have.

    >

    > Recursion is _trivial_ in Forth.  Simple recursion is handled by the word

    > RECURSE, which calls the containing word (which does not have to be named).

     Oh, good. As I have mentioned some earlier, my knowledge of Forth is

    based on the three or four books in our library which are over 20 years

    old. They either did not mention recursion at all, or they said explicitly

    that it is hard or awkward or something unappetising in Forth. I'm glad

    to hear that this has been fixed.

     >

    > Backtracking is almost as trivial, although the standard doesn't officially

    > support it, and it would be even easier with a way to return the current

    > continuation.  I've posted a paper about it, which I can repost if it's

    > needed.  It's a LOT simpler than most languages make it, and a LOT more

    > powerful.

     This sounds fascinating, I for one would certainly like to see it.

    On backtracking and what I said about alternation and fail:

    In non-strict (call-by-need or "lazy" implemented) languages

    like Haskell there is no need for alternation, fail, backtracking

    and so on. There is a paper by Wadler (?) "How to turn failure

    into a list of successes" (?). As I remember it, instead of having

    successes (possibly infinitely many) being produced one at a time

    (as in Prolog), you have a list of all these successes (an infinite

    list even), but because of the lazy evaluation it really is being

    produced only as far as needed, e.g. for printing. A far as I can

    tell this will not work for strict languages (Lisp, Scheme, ML, Joy)

    although there might be a way to implement "lazy lists" in the

    same way as it is done in ML (I believe). Does anybody know more?

    At any rate, leave alternation and fail out of Joy for the time being,

    but one could think about lazy lists.

      - Manfred

## Reuben Thomas — 2001-05-10 09:39:54

    > Oh, good. As I have mentioned some earlier, my knowledge of Forth is

    > based on the three or four books in our library which are over 20 years

    > old. They either did not mention recursion at all, or they said explicitly

    > that it is hard or awkward or something unappetising in Forth. I'm glad

    > to hear that this has been fixed.

     AFAIK, RECURSE is over 20 years old too, and I can't imagine why it could

    have been described as awkward, when it's just a call to the current word.

    --

    http://sc3d.org/rrt/ | maxim, n.  wisdom for fools

## Louis Madon — 2001-05-10 10:46:17

    From: "Reuben Thomas" <rrt@...>

     > > Oh, good. As I have mentioned some earlier, my knowledge of Forth is

    > > based on the three or four books in our library which are over 20 years

    > > old. They either did not mention recursion at all, or they said

     explicitly

     > > that it is hard or awkward or something unappetising in Forth. I'm glad

    > > to hear that this has been fixed.

    >

    > AFAIK, RECURSE is over 20 years old too, and I can't imagine why it could

    > have been described as awkward, when it's just a call to the current word.

     After looking up some info on the web it seems to me that 'RECURSE' only

    does self-recursion. What about mutual recursion, how do you do that in

    Forth?

    Louis.

## Reuben Thomas — 2001-05-10 11:30:05

    > After looking up some info on the web it seems to me that 'RECURSE' only

    > does self-recursion. What about mutual recursion, how do you do that in

    > Forth?

     Similarly simple but brutal: you write something like the following:

    DEFER B \ creates a vector for B

    : A ... B ... ; \ running A now will crash!

    : B-DEF ... A ... ; \ B-DEF can happily call A

    ' B IS B-DEF \ set the vector B to be B-DEF

    My memory of Forth is a little hazy at the moment, so I've probably got some

    details wrong, but this is the essence.

    Some Forths have nicer mechanisms to allow forward references to undefined

    words.

    --

    http://sc3d.org/rrt/ | perfect, a.  unsatirizable

## John Cowan — 2001-05-10 11:52:07

    Manfred von Thun scripsit:

     > "ifte" is easy to implement just in case the stack is a (linked)

    > list.

     I've actually been thinking about this.  It is easy to implement

    just in case the stack is a linked list *of immutable nodes*.  I am

    not sure that the current implementation preserves this property

    everywhere, and I suspect there may be problems.  If individual

    C definitions are allowed to alter stack elements that they are

    not going to pop later anyway, then it isn't enough to preserve

    the stack, as we now do, by preserving a pointer to its top:

    it would be necessary to actually copy the elements in case they

    get damaged later.  Ugh.

    I will look into fixing this when I get a chance.

    Note that this behavior of "ifte" and other combinators is a kind

    of hidden alternation: we run the if-part and then fail, dragging

    the top stack element with us.

     > At any rate, leave alternation and fail out of Joy for the time being,

    > but one could think about lazy lists.

     The Father has spoken, but if the immutable-node issue is once cleared

    out, I think the implementation of alternation/fail is very easy, and

    essentially restricted to the exeterm routine:

    	preserve the stack at the beginning on a new "choices" list;

    	restore it at the end;

    	make sure to handle tail recursion properly;

    	have another global setjmp buffer, and longjmp to it in order to fail;

    	on failure, iterate stepper to the next OR node and restore the stack;

    	on reaching an OR node normally, exit as if at end-of-quotation.

    Then we only need scanner/parser support for converting "|" into an OR node.

    --

    John Cowan                                   cowan@...

    One art/there is/no less/no more/All things/to do/with sparks/galore

    	--Douglas Hofstadter

## Manfred von Thun — 2001-05-10 11:07:48

    On Thu, 10 May 2001, Reuben Thomas wrote:

    (Hi Reuben, good to see that your are still there - Manfred)

    > > Oh, good. As I have mentioned some earlier, my knowledge of Forth is

    > > based on the three or four books in our library which are over 20 years

    > > old. They either did not mention recursion at all, or they said explicitly

    > > that it is hard or awkward or something unappetising in Forth. I'm glad

    > > to hear that this has been fixed.

    >

    > AFAIK, RECURSE is over 20 years old too, and I can't imagine why it could

    > have been described as awkward, when it's just a call to the current word.

    You made me go to the library to check my memory.

    Here is what we have, in chronological order:

    1981 Brodie, Leo, _Starting Forth_

         No conventional index, but an appendix with Forth words

         No "recurse" or "recursion" to be found.

    1883 Salman, Tisserand & Toulot, _Forth_

         No "recurse" or "recursion" in the (rather short) index.

         But gives (pp 106-7) a named recursive factorial with apologetic

         explanation about the need for SMUDGE.

         This is more than "just a call to the current word", as Reuben said.

         Also gives (pp 120-1) Hanoi and n-Queens with SMUDGE & recursion.

         [incidentally, there are two editors written on Forth here

          - somebody was asking for one in Joy to translate into Forth..]

    1985 Emery, Glyn, _The Student's Forth_

         No "recurse" or "recursion" word in Glossary.

         p 70 "Forth is not a recursive language" .."Mutual recursion..

         cannot be performed in  simple manner in Forth, since.."

         But on p 71 gives a non-recursive definition of factorial

         (for recursive execution) and .."some systems provide the

         equivalent [of three words] in the form of the word RECURSE".

    1986 Kelly & Spies, _FORTH A Text and Reference_

         p 171 "Recursion is .." "However, to use it [recursion] properly

         you must have a good understanding of the inner workings

         or Forth..". p 337 MYSELF as alternative to RECURSE. p 338

         example of factorial. p 339 "These exercises show that in

         most cases loops are preferable to recursion".

    1986 Reynolds, A.J. _Advanced FORTH_

         No "recursion" or cognates or "Myself" in index.

         Apparently not in the book either.

    1987 Pountain, Dick  _Object-Oriented Forth_

         No "recursion" or cognates or "Myself" in index.

         Apparently not in the book either.

         [but there is a lot in here about linked list implementations

         and freelists, memory in a heap - so here you go, Joy in Forth !]

    1989 Kail, P.A.C. _Forth A complete.._

         Index under "recursion" gives p 59 "(In some.. One way to do this

         would be to use the word IN-RANGE? inside itself: this

         is known as 'recursion'.)" And that is all there is about recursion.

    The few examples of recursion that I saw were just the sort of

    cases where indeed a looping solution would be just as good,

    or tail-recursion: the good ol' factorial. There was one exception:

    I found the n-Queens in Salman et.al. (1983) most interesting.

    It is too complex for me to understand, but it is noteworthy

    that this is the sort of problem that is often described as

    a typical backtracking problem. It appears that this program

    does give many solutions (p 122 second line from bottom says

    "Solution No. " ...)  But I am not so certain.

    Well, I'm not so sure why I did this all this. 10 p.m. now,

    good night, and I'll be back on Tuesday.

      - Manfred

## Reuben Thomas — 2001-05-10 12:52:27

    > 1883 Salman, Tisserand & Toulot, _Forth_

    >      No "recurse" or "recursion" in the (rather short) index.

    >      But gives (pp 106-7) a named recursive factorial with apologetic

    >      explanation about the need for SMUDGE.

    >      This is more than "just a call to the current word", as Reuben said.

     I was talking about how it's implemented, not how you type it. But typing

    : A [ SMUDGE ] ... A ... ;

    is much the same as typing

    : A ... RECURSE ... ;

     > 1985 Emery, Glyn, _The Student's Forth_

    >      No "recurse" or "recursion" word in Glossary.

    >      p 70 "Forth is not a recursive language" .."Mutual recursion..

    >      cannot be performed in  simple manner in Forth, since.."

     I don't think that vectoring is exactly complex!

     > 1986 Kelly & Spies, _FORTH A Text and Reference_

    >      p 171 "Recursion is .." "However, to use it [recursion] properly

    >      you must have a good understanding of the inner workings

    >      or Forth..". p 337 MYSELF as alternative to RECURSE. p 338

    >      example of factorial. p 339 "These exercises show that in

    >      most cases loops are preferable to recursion".

     The attitude that iteration is usually better is a typical imperative

    programmer's prejudice. But the idea that you need to have a good

    understanding of the inner workings is bizarre. What's complicated about

    RECURSE?

    But your recollections of the literature are certainly accurate. I guess

    that recursion just didn't get in to the mainstream for a long time.

    --

    http://sc3d.org/rrt/ | Si hoc legere scis nimium eruditionis habes. (Anon)

## John Cowan — 2001-05-10 16:04:15

    Blunderingly I wrote:

     >

    > 	preserve the stack at the beginning on a new "choices" list;

    > 	restore it at the end;

     Of course I meant to say "pop choices at the end", not "restore the stack".

     > 	make sure to handle tail recursion properly;

    > 	have another global setjmp buffer, and longjmp to it in order to fail;

     We also need to capture the current contents of this buffer at the beginning

    of every exeterm, and restore it at the end.  This can be achieved by

    storing its contents in the C stack as a local variable, since it is not

    a root of GC.

     > 	on failure, iterate stepper to the next OR node and restore the stack;

    > 	on reaching an OR node normally, exit as if at end-of-quotation.

     --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## Billy Tanksley — 2001-05-11 02:03:07

    From: Manfred von Thun [mailto:phimvt@...]

     >On Tue, 8 May 2001, Billy Tanksley wrote:

    >> From: Manfred von Thun [mailto:phimvt@...]

    >> >On Thu, 3 May 2001, Dirk-Ulrich Heise wrote:

    >> I don't share your admiration of ifte, by the way.  It looks

    >> good at first,

    >> but in reality it adds a LOT of difficulty, both in reading,

    >> writing, and

    >> compiling.  But then the entire concept of branching has its own

    >> difficulties :-).

    >Do you mean just "ifte", or do you mean all combinators that

    >have a test,

    >like "whiledo" "linrec" "binrec" "treegenrec"? Or do you even mean all

    >combinators?

     Hmm...  I mean the idea of accepting a function on the stack and

    conditionally executing it.  I'm not only talking about the test; I'm

    talking about both branches as well.  Being able to do that adds a lot of

    overhead to an interpreter or compiler, and doing it adds a lot of visual

    complexity to a program.

    Joy isn't going to get rid of [quotations], nor should it, but it might help

    to have a few words to minimise the need to use them.

    Forthers have found that the need for 'else' blocks goes away if you write

    very small definitions, like this:

    define: myWord  ( flag -- )

       if true-part-of-myword EXIT endif false-part-of-myWord

    end-definition;

    Notice the EXIT in there?  EXIT substitutes for ELSE by making sure the

    control-flow for the true statement stops, and then the rest of myWord

    becomes the ELSE clause.

    So, here's a word Joy could use:

    'conditionally' consumes a flag and a quotation, and if the flag's true

    executes the quotation and returns from the caller.  If the flag's false it

    just continues executing.

     >"ifte" is easy to implement just in case the stack is a (linked)

    >list. It would be much harder if the stack is a (consecutive memory)

    >array  --  as in Forth. But one might well just have a "branch"

    >instead, and leave the work to the programmer (I take it, with a

    >few dups and saving on the return stack and later restoring).

     In Forth, the word 'IF' immediately compiles an unresolved conditional jump

    and drops the address needed to resolve it on the compile-stack.  ELSE

    immediately resolves a conditional jump, then compiles an unresolved

    unconditional jump and leaves its address on the stack.  THEN immediately

    resolves an unresolved jump, which may be conditional or unconditional.

     >> >But (not knowing Forth)

    >> >as far as I know recursion is hard in Forth, and so would be

    >> >any recursive combinator. Let us see what you have.

    >> Recursion is _trivial_ in Forth.  Simple recursion is

    >> handled by the word

    >> RECURSE, which calls the containing word (which does not

    >> have to be named).

    >Oh, good. As I have mentioned some earlier, my knowledge of Forth is

    >based on the three or four books in our library which are over 20 years

    >old. They either did not mention recursion at all, or they

    >said explicitly

    >that it is hard or awkward or something unappetising in Forth. I'm glad

    >to hear that this has been fixed.

     The main problem was documentation -- most people writing Forth

    documentation didn't understand recursion, and didn't want to have to teach

    it.

     >> Backtracking is almost as trivial, although the standard

    >> doesn't officially

    >> support it, and it would be even easier with a way to return

    >> the current

    >> continuation.  I've posted a paper about it, which I can

    >> repost if it's

    >> needed.  It's a LOT simpler than most languages make it, and

    >> a LOT more powerful.

    >This sounds fascinating, I for one would certainly like to see it.

     http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt is a short paper which

    communicates the essence.  The author posts to comp.lang.forth, so I can ask

    for more info if you'd like.

     >list even), but because of the lazy evaluation it really is being

    >produced only as far as needed, e.g. for printing. A far as I can

    >tell this will not work for strict languages (Lisp, Scheme, ML, Joy)

    >although there might be a way to implement "lazy lists" in the

    >same way as it is done in ML (I believe). Does anybody know more?

    >At any rate, leave alternation and fail out of Joy for the time being,

    >but one could think about lazy lists.

     Yes...  I can see how this might work.  You'd have to redefine the nature of

    lists, so that instead of being memory structures they are generator

    functions.  Let me see...

    [1 2 3 4 5] == denotes a generator which returns 1, then 2, then 3, then 4,

    then 5, then fails.

    {integers} == is a generator which returns the integers, starting at 1.

    [1 2 3 4 5] cdr == denotes a generator which returns [2, 3, 4, 5].

    car == the way to call a generator.

    add-condition == adds a conditional to a generator, making it skip producing

    items for which the conditional is false.

    {integers} [2 mod 0 !=] add-condition == denotes a generator for the odd

    integers.

    I like it.

     >  - Manfred

     -Billy

## John Cowan — 2001-05-11 15:49:36

    Billy Tanksley wrote:

     > So, here's a word Joy could use:

    >

    > 'conditionally' consumes a flag and a quotation, and if the flag's true

    > executes the quotation and returns from the caller.  If the flag's false it

    > just continues executing.

     This is what Common Lisp calls "when".  It's trivial to add:

    DEFINE conditionally == [] ifte.  Perhaps we could do it in C as well.

     > http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt

     Interesting.

    --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## Billy Tanksley — 2001-05-11 17:29:48

    From: John Cowan [mailto:cowan@...]

     >Billy Tanksley wrote:

    >> So, here's a word Joy could use:

    >> 'conditionally' consumes a flag and a quotation, and if the

    >> flag's true

    >> executes the quotation and returns from the caller.  If the

    >> flag's false it just continues executing.

    >This is what Common Lisp calls "when".  It's trivial to add:

    >DEFINE conditionally == [] ifte.  Perhaps we could do it in C as well.

     That doesn't return from the caller, nor does it take its parameter from the

    stack.  It's a good idea anyhow, on the basis that it's simpler to write.

     >> http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt

    >Interesting.

     Some surprising things in there.  I never realised just how powerful the

    exposed return stack in Forth could be.  It could be even more powerful in

    Joy, since Joy doesn't use the return stack for any other purposes.

     >There is / one art             || John Cowan <jcowan@...>

     -Billy

## Manfred von Thun — 2001-05-15 05:45:21

    On Thu, 10 May 2001, John Cowan wrote:

     > Manfred von Thun scripsit:

    >

    > > "ifte" is easy to implement just in case the stack is a (linked)

    > > list.

    >

    > I've actually been thinking about this.  It is easy to implement

    > just in case the stack is a linked list *of immutable nodes*.

     Yes, that is how it has to be.

     >  I am

    > not sure that the current implementation preserves this property

    > everywhere, and I suspect there may be problems.  If individual

    > C definitions are allowed to alter stack elements that they are

    > not going to pop later anyway, then it isn't enough to preserve

    > the stack, as we now do, by preserving a pointer to its top:

    > it would be necessary to actually copy the elements in case they

    > get damaged later.  Ugh.

     When I wrote my prototype, I was constantly tempted to

      1. Re-use nodes for unary, binary and other operators,

         just as one would with a stack-based implementation.

         BUT in a functional language this is a NO-NO, there

         may be other pointers to the node, and what they

         point to must not be overwritten.

      2. Use local C-variables to save (and later restore)

         nodes on the Joy stack. That MAY be OK if the language

         is garbage collected (as C is not), but it is not

         OK if one is writing one's own garbage collector,

         as I had to do.

    It took me a while to unlearn a number of things that had

    become second nature in most of what I had been doing before.

    I am fairly confident that my current version does not commit

    any of the above sins. It is essential that future versions

    ot be adulterated.

     >

    > I will look into fixing this when I get a chance.

     Good.

    ...

     > > At any rate, leave alternation and fail out of Joy for the time being,

    > > but one could think about lazy lists.

    >

    > The Father has spoken, but if the immutable-node issue is once cleared

    > out, I think the implementation of alternation/fail is very easy, and

    > essentially restricted to the exeterm routine:

    >

    > 	preserve the stack at the beginning on a new "choices" list;

    > 	restore it at the end;

    > 	make sure to handle tail recursion properly;

    > 	have another global setjmp buffer, and longjmp to it in order to fail;

    > 	on failure, iterate stepper to the next OR node and restore the stack;

    > 	on reaching an OR node normally, exit as if at end-of-quotation.

     There is also the matter of flow of control, and if you try to

    implement in C just that fragent of my regular expression expander

    from my Pascal page that can expand

           (a | b) (c | d)

    i.e. no Kleene star "*", you will see what I mean. It is hard

    if continuations cannot be handled properly. But don't let me

    discourage you too early.

      - Manfred

## Manfred von Thun — 2001-05-15 05:55:52

    On Fri, 11 May 2001, Billy Tanksley wrote:

     > From: John Cowan [mailto:cowan@...]

    > >Billy Tanksley wrote:

    >

    > >> http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt

    > >Interesting.

    >

    > Some surprising things in there.  I never realised just how powerful the

    > exposed return stack in Forth could be.  It could be even more powerful in

    > Joy, since Joy doesn't use the return stack for any other purposes.

     Ideed, using local variables in C functions for saving and later

    restoring the Joy stack would be disastrous.

    One can of course save the entire Joy stack with the "stack" operator.

    The following must hold:

        stack  [mangle-the-stack]  dip  unstack   ==   id

    where "id" of course is the identity function. In other words, the net

    effect of the left side is to do nothing at all.

    Saving the entire Joy stack with "stack" is just a single push of

    a single node, since the stack is a linked list.

    So whatever you might be tempted to do by using the return stack

    of C by local variables can already be done quite simply.

      - Manfred

## John Cowan — 2001-05-15 13:45:40

    Manfred von Thun wrote:

     > There is also the matter of flow of control, and if you try to

    > implement in C just that fragent of my regular expression expander

    > from my Pascal page that can expand

    >        (a | b) (c | d)

    > i.e. no Kleene star "*", you will see what I mean.

     My approach would be to compile out parentheses, so that the

    above would be stored and executed as "a c | a d | b c | b d".

    That allows linear, rather than tree-like, alternation

    at run time.

    As a first cut, I plan to not allow parens at all, but simply

    to require the user to write the normal form above.

    --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## John Cowan — 2001-05-15 13:49:38

    Manfred von Thun wrote:

     > So whatever you might be tempted to do by using the return stack

    > of C by local variables can already be done quite simply.

     To implement alternation, though, one must be able to store the

    C-level continuation, and the way to do that is "setjmp".  A

    jmp_buf may be arbitrarily large (processor-dependent) since it

    has to restore the processor registers.  The C stack is clearly

    the right place to save and restore this.  If one is careful with

    the "volatile" qualifier, which forces local variables so marked

    to be stored in the stack, one can get good results.

    It is still necessary to save and restore the Joy stack on a new list,

    "choices", which is a GC root.  One irritating problem is that

    there is nowhere to memoize which quotations have alternation and

    which don't, so one ends up pre-scanning every quotation before

    executing it in order to decide whether it contains choice points or

    not.

    --

    There is / one art             || John Cowan <jcowan@...>

    no more / no less              || http://www.reutershealth.com

    to do / all things             || http://www.ccil.org/~cowan

    with art- / lessness           \\ -- Piet Hein

## Billy Tanksley — 2001-05-15 17:02:28

    From: Manfred von Thun [mailto:phimvt@...]

     >On Fri, 11 May 2001, Billy Tanksley wrote:

    >> From: John Cowan [mailto:cowan@...]

    >> >Billy Tanksley wrote:

    >> >> http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt

    >> >Interesting.

    >> Some surprising things in there.  I never realised just how

    >> powerful the

    >> exposed return stack in Forth could be.  It could be even

    >> more powerful in

    >> Joy, since Joy doesn't use the return stack for any other purposes.

    >Ideed, using local variables in C functions for saving and later

    >restoring the Joy stack would be disastrous.

     When I first read this, I was mildly confused by the use of the word "C".  I

    hadn't mentioned that...

     >So whatever you might be tempted to do by using the return stack

    >of C by local variables can already be done quite simply.

     Ah.  I'm starting to suspect that you read something into my essay.

    C doesn't have a return stack; it only has a frame stack, which is used for

    call frames (consisting of local variables, parameters, and return

    addresses).  To the best of my knowledge, Forth is the only language which

    uses a return stack.  Furthermore, even the ANSI standard Forth exposes that

    return stack for some limited uses, and most implementations allow

    full-powered exposure of return addresses.

     >  - Manfred

     -Billy

## Manfred von Thun — 2001-05-16 03:07:06

    On Thu, 10 May 2001, Billy Tanksley wrote:

     > From: Manfred von Thun [mailto:phimvt@...]

    > >On Tue, 8 May 2001, Billy Tanksley wrote:

     [some earlier dialogue deleted]

     > >Do you mean just "ifte", or do you mean all combinators that

    > >have a test,

    > >like "whiledo" "linrec" "binrec" "treegenrec"? Or do you even mean all

    > >combinators?

    >

    > Hmm...  I mean the idea of accepting a function on the stack and

    > conditionally executing it.  I'm not only talking about the test; I'm

    > talking about both branches as well.  Being able to do that adds a lot of

    > overhead to an interpreter or compiler, and doing it adds a lot of visual

    > complexity to a program.

     There is very little overhead for the interpreter, just a

    push-this-program instruction. An optimising interpreter might

    even be able to avoid the push-push-push for ifte and put the

    three programs elsewhere where they have to be put eventually

    anyhow (on the dumps in the prototype - but these are supposed

    to be invisible to the user). As to visual complexity, it is

    pretty much the same as in most other languages, it seems to me.

    Here is a factorial function in Lispish/Schemish notation:

        (define  (factorial n)

                 (if

                     (<= 1 n)                         (* test *)

                     (1)                              (* bottom *)

                     (* n factorial (- n 1)) ) )      (* recursion *)

    Compare with Joy:

        DEFINE  factorial  ==

                [1 <=]                                (* test *)

                [pop 1]                               (* bottom *)

                [dup 1 - factorial *]                 (* recursion *)

                ifte.

    The three parts are just about the same, of course.

     > Joy isn't going to get rid of [quotations], nor should it, but it might

     help

     > to have a few words to minimise the need to use them.

    >

    > Forthers have found that the need for 'else' blocks goes away if you write

    > very small definitions, like this:

    >

    > define: myWord  ( flag -- )

    >    if true-part-of-myword EXIT endif false-part-of-myWord

    > end-definition;

    >

    > Notice the EXIT in there?  EXIT substitutes for ELSE by making sure the

    > control-flow for the true statement stops, and then the rest of myWord

    > becomes the ELSE clause.

     Yes, clever. But:

        1. What is the reason for wanting to eliminate 'else' blocks?

        2. Those very small definitions clog up the symbol tables in

           a) the computer (but that does not matter)

           b) the mind (and I think this matters a great deal)

    However, I shall think about this suggestion, thanks.

    [on backtracking in Forth:]

     > http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt is a short paper which

    > communicates the essence.  The author posts to comp.lang.forth, so I can ask

    > for more info if you'd like.

     Yes please, I think John Cowan might be interested for his backtracking

    in Joy

      - Manfred

## Manfred von Thun — 2001-05-16 03:18:00

    On Tue, 15 May 2001, John Cowan wrote:

     > Manfred von Thun wrote:

    >

    >

    > > There is also the matter of flow of control, and if you try to

    > > implement in C just that fragent of my regular expression expander

    > > from my Pascal page that can expand

    > >        (a | b) (c | d)

    > > i.e. no Kleene star "*", you will see what I mean.

    >

    > My approach would be to compile out parentheses, so that the

    > above would be stored and executed as "a c | a d | b c | b d".

    > That allows linear, rather than tree-like, alternation

    > at run time.

     Two comments:

        1. Consider the exponential explosion of concatenations of

        alternations. If each alternation is of the form (x | y)

        with just two alternands, then a concatenation of ten such

        alternations will give you 10^2 = 1024 alternations in

        the expanded form.

        2. Yes, the run-time alternation will be linear (and hence

        more efficient, too. But the compilation from tree to

        linear will not be as easy as you might think. This is

        the same as the nasty little exercise I suggested above.

      - Manfred

## Manfred von Thun — 2001-05-16 03:30:09

    On Tue, 15 May 2001, John Cowan wrote:

     > Manfred von Thun wrote:

    >

    > > So whatever you might be tempted to do by using the return stack

    > > of C by local variables can already be done quite simply.

    >

    > To implement alternation, though, one must be able to store the

    > C-level continuation, and the way to do that is "setjmp".  A

    > jmp_buf may be arbitrarily large (processor-dependent) since it

    > has to restore the processor registers.  The C stack is clearly

    > the right place to save and restore this.  If one is careful with

    > the "volatile" qualifier, which forces local variables so marked

    > to be stored in the stack, one can get good results.

     You know a lot more about setjmp than I do. I have only used

    it for "escape from error, back to main", the sort of thing

    which in Pascal tends to be a simple "GOTO 1", where the label 1

    is in the main program.

    I have implemented alternation in C in two ways. 1: using the

    C-stack and passing funny parameters on that, and 2: passing these

    funny gizmos on a separate hand made special stack. None of them

    are too beautiful. It is all so much cleaner in Pascal where

    one has access to non-local non-global variables in the block

    structure through the static links (or display). Only one of

    my students ever found a C-solution, and I think it was the same

    as one of mine.

      - Manfred

## Manfred von Thun — 2001-05-16 03:57:01

    On Tue, 15 May 2001, Billy Tanksley wrote:

     > >Ideed, using local variables in C functions for saving and later

    > >restoring the Joy stack would be disastrous.

    >

    > When I first read this, I was mildly confused by the use of the word "C".  I

    > hadn't mentioned that...

     Sorry, I was talking about the C stack in the Joy implementation

    written in the C language.

     > >So whatever you might be tempted to do by using the return stack

    > >of C by local variables can already be done quite simply.

    > C doesn't have a return stack; it only has a frame stack, which is used for

    > call frames (consisting of local variables, parameters, and return

    > addresses).

     That is correct. (Note, mainly for John Cowan: and Pascal also has

    a fourth thing - the static link to frames of enclosing blocks.

    This is what makes continuations so easy to do in Pascal.)

    I meant this very same stack common to all the Algolic languages.

      - Manfred

## Manfred von Thun — 2001-05-22 02:02:36

    On Wed, 16 May 2001, Manfred von Thun wrote:

     >

    > On Thu, 10 May 2001, Billy Tanksley wrote:

    >

    > > From: Manfred von Thun [mailto:phimvt@...]

    > > >On Tue, 8 May 2001, Billy Tanksley wrote:

    > [lots of earlier dialogue deleted]

    >

    > > Joy isn't going to get rid of [quotations], nor should it, but it might

    > help

    > > to have a few words to minimise the need to use them.

    > >

    > > Forthers have found that the need for 'else' blocks goes away if you write

    > > very small definitions, like this:

    > >

    > > define: myWord  ( flag -- )

    > >    if true-part-of-myword EXIT endif false-part-of-myWord

    > > end-definition;

    > >

    > > Notice the EXIT in there?  EXIT substitutes for ELSE by making sure the

    > > control-flow for the true statement stops, and then the rest of myWord

    > > becomes the ELSE clause.

    >

    > Yes, clever. But:

    >     1. What is the reason for wanting to eliminate 'else' blocks?

    >     2. Those very small definitions clog up the symbol tables in

    >        a) the computer (but that does not matter)

    >        b) the mind (and I think this matters a great deal)

    > However, I shall think about this suggestion, thanks.

     Thinking about EXIT in Joy, let me get it straight. Here is your

    definition again:

        define: myWord  ( flag -- )

           if true-part-of-myword EXIT endif false-part-of-myWord

        end-definition;

    To make this compatible with Joy notation, I'll write it in the usual

    definition style and also write IF in captitals because it is different

    from the ordinary "if" in Joy, also write ENDIF in capitals:

        DEFINE

            myWord  ==

                IF  true-part-of-myWord  EXIT  ENDIF  false-part-of-myWord.

    So EXIT causes the false-part-of-myword to be skipped. Suppose now we

    have

        DEFINE

            anotherWord  ==

               first-part

               myWord

               last-part.

    If insider anotherWord it happens that myWord is executed with

    an EXIT, then false-part-of-myWord is NOT executed, but last-part

    of anotherWord IS executed. But the body of a definition is supposed

    to be entirely equivalent to calling the defined word. So this

    should do te same:

        DEFINE

            anotherWord  ==

               first-part

               IF  true-part-of-myWord  EXIT  ENDIF  false-part-of-myWord

               myWord

               last-part.

    In this version of anotherWord I have simply substituted the body

    of myWord for the call to myWord. If the EXIT is executed, then

    false-part-of-myWord is NOT executed (which is correct), but

    last-part of anotherWord is NOT executed either (but it should be).

    So, here is my analysis: EXIT to the end of a definition violates

    the following principle of concatenative languages:

          After a definition of the form

             DEFINE  Word  ==  Body.

          the equation

                   Word    ==    Body

          holds, and by substitutivity in contexts

                 F Word G  ==  F Body G

          also hold for all functions F and G.

    I conclude that EXIT should not be part of Joy.

    It is quite possible that I misunderstood something about EXIT.

    If so, I would appreciate some clarification. In any case it was

    useful for me to think this through, so thanks Billy.

     >

    > [on backtracking in Forth:]

    > > http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt is a short paper which

    > > communicates the essence.  The author posts to comp.lang.forth, so I can ask

    > > for more info if you'd like.

    > Yes please, I think John Cowan might be interested for his backtracking

    > in Joy

     I had a look at this page and quite a few others which I found by

    a google search for  "Forth backtrack" and "Forth backtracking".

    So there seems to be a fair amount of interest in that. But I must

    confess that I could not really understand it - it clearly requires

    a very solid understanding of Forth internals.

      - Manfred

## John Cowan — 2001-05-22 11:33:23

    Manfred von Thun scripsit:

     > So, here is my analysis: EXIT to the end of a definition violates

    > the following principle of concatenative languages:

    >       After a definition of the form

    >          DEFINE  Word  ==  Body.

    >       the equation

    >                Word    ==    Body

    >       holds, and by substitutivity in contexts

    >              F Word G  ==  F Body G

    >       also hold for all functions F and G.

     By that standard, all of the Forth "compile-time-only" words like if,

    else, then are not concatenative.  In effect, they are pure syntax,

    like Joy == and DEFINE/LIBRA and HIDE...IN.

     > I conclude that EXIT should not be part of Joy.

     I agree.

    --

    John Cowan                                   cowan@...

    One art/there is/no less/no more/All things/to do/with sparks/galore

    	--Douglas Hofstadter

## Billy Tanksley — 2001-05-23 00:29:59

    From: Manfred von Thun [mailto:phimvt@...]

     >So, here is my analysis: EXIT to the end of a definition violates

    >the following principle of concatenative languages:

    >      After a definition of the form

    >         DEFINE  Word  ==  Body.

    >      the equation

    >               Word    ==    Body

    >      holds, and by substitutivity in contexts

    >             F Word G  ==  F Body G

    >      also hold for all functions F and G.

    >I conclude that EXIT should not be part of Joy.

     That's correct, and sounds reasonable to me, since Joy is supposed to be a

    simple demonstration of certain properties.

    I don't believe it actually violates a property of concatenative languages,

    though; it simply extends the property to the continuation stack.  The

    result, though, it to introduce some complications into the rules we already

    know, so I con completely understand you not wanting to include it.

     >> [on backtracking in Forth:]

    >> > http://www.forth.org.ru/~mlg/ef94/ef94-2-paper.txt is a

    >> > short paper which

    >> > communicates the essence.  The author posts to

    >> > comp.lang.forth, so I can ask

    >> > for more info if you'd like.

    >I had a look at this page and quite a few others which I found by

    >a google search for  "Forth backtrack" and "Forth backtracking".

    >So there seems to be a fair amount of interest in that. But I must

    >confess that I could not really understand it - it clearly requires

    >a very solid understanding of Forth internals.

     I can see how that would block an in-depth understanding; however, I believe

    that the basics are very approachable on the basis of a general theoretical

    education.

    In order to understand it, you have to think in terms of a new stack, called

    the "return stack" or "continuation stack".  Every time a function is

    called, the current IP is pushed on the return stack before transferring

    control to the function; when the word's finished executing, it'll pop the

    address off the stack and transfer control back to it.

    With me so far?

    Now, we have some words, Rfrom and intoR, to push and pop continuations

    (return addresses) between the data stack and return stack.  We also have a

    word, EXIT, which exits the current definition (thereby transferring control

    to the item on top of the return stack).

    This word set is sufficient to implement everything possible in any

    continuation system, and allows unlimited abstraction.

     >  - Manfred

     -Billy

## Manfred von Thun — 2001-06-05 02:30:54

    On Tue, 22 May 2001, Billy Tanksley wrote:

    [apropos backtracking in Forth]

    > In order to understand it, you have to think in terms of a new stack, called

    > the "return stack" or "continuation stack".  Every time a function is

    > called, the current IP is pushed on the return stack before transferring

    > control to the function; when the word's finished executing, it'll pop the

    > address off the stack and transfer control back to it.

    >

    > With me so far?

    Yes. In fact Joy has an operator "conts" which pushes a list of

    programs on the stack. This is list was constructed by any calls

    done previously, and it contains the outstanding continuation

    calls. I added an extra internal register to Joy just for this

    purpose, and constructing the list of continuations does add to

    runtime all the time.

    To my shame I must admit I never managed to do anything remotely

    useful with it. It can be used for debugging, typically by

        conts  putln                (* "ln"=terminate with newline *)

    but that is about all. I tried a few other things, to no avail.

    The  callcc  in one of the standard libraries was supposed to

    emulate Scheme's callcc , but again I have not managed to do

    something useful. It may even be that any of it ruins referential

    transparency and/or the substitution principle, which I argued

    must be retained when I argued about the exit-from-definition

    which you introduced into the discussion.

    Maybe somebody can take up the matter of making use of  conts .

    Otherwise I'll eventually delete conts and the continuation

    register.

      - Manfred

## John Cowan — 2001-06-05 05:21:38

    Manfred von Thun scripsit:

     > The  callcc  in one of the standard libraries was supposed to

    > emulate Scheme's callcc , but again I have not managed to do

    > something useful.

     I was planning to ask just how Joy callcc works (I understand how

    Scheme call/cc works).

    Note that conts sometimes pushes a null on the stack which causes

    a crash.  Load joy and say "conts." and down we go.

    I think it needs to be rethought.

    --

    John Cowan                                   cowan@...

    One art/there is/no less/no more/All things/to do/with sparks/galore

    	--Douglas Hofstadter

## Manfred von Thun — 2001-06-05 06:50:12

    On Tue, 5 Jun 2001, John Cowan wrote:

     > I was planning to ask just how Joy callcc works (I understand how

    > Scheme call/cc works).

     (embarrassed blush) It doesn't, sorry.

     >

    > Note that conts sometimes pushes a null on the stack which causes

    > a crash.  Load joy and say "conts." and down we go.

    >

    > I think it needs to be rethought.

     Indeed. I did not know about the crash. Maybe it needs proper

    initialisation. The following does work (almost!) as intended:

    [1 2 3 4]  [dup *]  map .                  (* the usual *)

    [1 2 3 4]  [dup *]  map  dup swap pop .    (* silly stuff at end *)

    Now look at the conts:

       [1 2 3 4]

       [ dup put  ": conts = " putchars  conts putln

         dup * ]

       map  dup swap pop.

    It is not quite right, because the output is

    1 : conts = [[dup *] [dup swap pop]]

    2 : conts = [[dup *] [dup swap pop]]

    3 : conts = [[dup *] [dup swap pop]]

    4 : conts = [[dup *] [dup swap pop]]

    [1 4 9 16]

    but the conts in each line should be [[putln dup *] [dup swap pop]]

    So indeed there is a bug somewhere.

    Possibly when conts is fixed one could work on callcc.

    Certainly you are the one who should do it. (Friendly grin)

      - Manfred

## Manfred von Thun — 2001-06-15 07:13:39

    I have now posted the ANNOUNCE to comp.lang.functional

    What do members of the group think about also posting to other

    newsgroups:

    comp.lang.theory

    comp.lang.misc

    comp.lang.forth

    any others?

    My understanding is that too much advertising one's own pages

    is not appreciated. Any opinions?

    I had included a reference to John Cowan's Joy1 on the

    main Joy page early June, but it is still only a link.

    I'll make a local copy as soon as John says I should.

    (And, John, do put your own name beside mine on the

    copyright notice  --  unless you have special reasons

    for not wanting to.)

    A day ago I updated the Joy0 souce files in C to make them

    compatible with a small number of changes that I had asked

    John to put into Joy1.

    I have dug out an antique version of Joy in (would you believe)

    Common Lisp which I once wrote when we had a Data General

    machine. I added it to the "Miscellaneous" on the main

    Joy page.

    Recently I have been working on matrix addition and multiplication

    operators and combinators of increasing generality. I will be

    able to add a new page concerning that. At the same time

    I'll change the standard library a bit, because that is

    necessary now with the new Joy1 and Joy0. (In case you are

    wondering, no, I do not plan to keep on revising Joy0.

    Just this once.)

    I also realise that many of the papers could do with a thorough

    workover and updates.

    I hope you all are well and thriving.

      - Manfred