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