Re: [stack] Forth/Joy cross fertilization.

Martin Young — 2000-08-21 13:24:06

On Aug 21, 2:37pm, phimvt@... wrote:
> Forth and Joy both use postfix notation to manipulate a stack. This
> invites further comparisons, and raises the hope that they could profit
> from in ech other in ways that are _specific_ (emphasise SPECIFIC)
> to the two languages and not to others. I feel forced to conclude
> that this view is mistaken. Let me explain.
[snip]
> 2. Access to its own internal working, in particular access to addresses.
> Of course Forth provides this. So do C and some extensions of
> Pascal. The Lisps, Prolog, ML and Haskell do not, as far as I know.
> This is because it is against their aim: to provide a portable
> programmable high level machine that is independent of its implemen-
> tation. The same holds for Joy.

I would argue that Prolog (which I know quite well), Haskell (which I know only
a little) and Joy *do* offer access to their own internal workings.

The main abstraction in the C/Pascal familiy of languages is to give symbolic
names to memory locations, i.e. staic varibles name fixed locations, automatics
name offsets from the stack base, functions name locations in the program text
and so forth. Thus to provide access to its own internal workings the language
needs only to allow the programmer access to the underlying addresses and some
means to manipilate them. C does this but does not provide access to control
flow (e.g. you don't have access to the nature of the current code block).

Higher level languages have different abstractions. For example, Prolog is
based on a database of terms. A term is a functor (effectively the rule's
name) and a number of parameters. A rule, for example, consists of the functor
":-" (implies) and some number of parameters where the first is the implication
of the others being true. For the ground case Prolog provides atoms where an
atom in an indivisable datum often a number or a word.

Prolog allows the programmer to deconstruct anything (including the program
itself) down to the level of terms and atoms. Some implementations allow the
symbolic names of atoms to be reintroduced in the form of strings (lists of
character codes). Some implementations also allow destructive updates. There
are a large collection of meta-programming predicates which allow program flow
to be manipulated.

In this way, Prolog actually provides *greater* access to its own workings than
does C (because C doesn't let you examine the internal structure of functions
and the stack/heap). AFAIK Haskell offers analogous features but strictly
(haha) without desctructive update.

Joy's quoted programs offer the same level of introspection. With a suitable
implementation of visible continuations the control flow is available too.

The use to addresses to manipulate entities outside of the program (e.g.
hardware devices) would be covered by point 1 of the original message.

> 4. Manipulating the symbol table. This is quite different
> from 2. and deserves separate discussion. Forth can treat the symbol
> table like any other data structure. No other language does it to the
> same extent.

Again, in the case of Prolog, the programmer has complete control over the
symbol table.

> 5. The "CREATE(BUILD)..DOES.." duo. This is an immensely powerful
> feature, and as far as I can tell no other language has anything like
> it (CLOS might be an exception - does anyone know?). I suspect it
> cannot be fully emulated by a macro preprocessor. D. Pountain (1987,
> _Object Orianted Forth_) defines second order words in which the
> DOES-part contains the same construct again. He uses the method to
> implement records, abstract data types and lists, including garbage
> collection (useful for a Joy-in-Forth).

I've not done much programming in forth but I'm given to understand that
"CREATE(BUILD)...DOES" adds a new word to the language by specifying some
compile-time and some execution-time words which constitute its definition.

I'm starting to sound obsessed: Prolog allows the programmer to add to the
program in this manner. I'm not advocating that all forth programmers
immediately switch to Prolog rather that these features are not consequences
only of the stack based approach to programming.

> Points 1..5 are of course incomplete and superficial. But they do
> suggest that whatever cross-fertilisation there might be between
> Forth and Joy it will not be due to the common postfix notation.

I'm not sure I agree. Forth programs share many simple words with Joy programs
(e.g. swap, dup, roll and so forth (haha, again), and both languages make very
light use to symbolic names for values. I suspect that an algorithm expressed
in both langauges will look quite similar.

I think there is much to be gained by Joy from looking at complex problems
solved in forth and asking how it was done using only the stack. I find the
structure of my Joy programs often disappears in a sea of dups and swaps: how
to forth programmer avoid this? What abstractions do they use to express
algorithms?

> In the reverse direction, and independent of postfix
> notation, here are some projects:

> b) Examine the desirability of adding "CREATE..DOES.." to Joy.
> This might be in tandem with a) or quite independently.

I've got a knee-jerk reaction to this: it's a really, really bad idea. It
makes the semantics of a program undecidable with the following consequences:
optimisation becomes really difficult; programs become difficult to debug;
reasoning about the program is almost impossible; a true compiler would be
handicapped; the semantics of already extant code could be changed.

Moreover, why would it be useful? Joy already allows programs to be constructed
and deconstructed on the fly.

> c) Investigate the power of macros. For text macros a useful starting
> point would be the unix macro preprocessor m4. For syntax macros
> (in Joy itself) some extensions (presumably 2.) are likely to be
> necessary.

A pre-processor, on the other hand, is probably useful. Joy already has it to
some extent: the top level scanner changes [...] into a list and {...} into a
set etc, and the == notation is pretty close to a macro anyway.

I'm not sure what you mean by "syntax macros".

--
Martin Young working for STMicroelectronics at `(o)_(o)' The fat wise /
1000 Aztec West, Almondsbury, Bristol, BS32 4SQ. ( V ) owl eats only >
+44 1454 462 523 `v' Martin.Young@... `.___,' clean mice. /
_(_)_ -="==="=============='

wtanksley@bigfoot.com — 2000-08-21 17:58:38

From: Martin Young [mailto:martin.young@...]
>On Aug 21, 2:37pm, phimvt@... wrote:

>> 4. Manipulating the symbol table. This is quite different
>> from 2. and deserves separate discussion. Forth can treat the symbol
>> table like any other data structure. No other language does it to the
>> same extent.

>Again, in the case of Prolog, the programmer has complete
>control over the symbol table.

I've done somre work in Prolog, and I didn't notice this.

>> 5. The "CREATE(BUILD)..DOES.." duo. This is an immensely powerful
>> feature, and as far as I can tell no other language has anything like
>> it (CLOS might be an exception - does anyone know?). I suspect it
>> cannot be fully emulated by a macro preprocessor. D. Pountain (1987,
>> _Object Orianted Forth_) defines second order words in which the
>> DOES-part contains the same construct again. He uses the method to
>> implement records, abstract data types and lists, including garbage
>> collection (useful for a Joy-in-Forth).

>I've not done much programming in forth but I'm given to
>understand that
>"CREATE(BUILD)...DOES" adds a new word to the language by
>specifying some
>compile-time and some execution-time words which constitute
>its definition.

CREATE defines a new word with no action (except to return the address of
its data field, which is unallocated). DOES> modifies the last CREATE word
to do some other action with that address.

>I'm starting to sound obsessed: Prolog allows the programmer
>to add to the program in this manner.

Again, how? This doesn't sound AT ALL like the Prolog I learned.

>I'm not advocating that all forth programmers
>immediately switch to Prolog rather that these features are
>not consequences
>only of the stack based approach to programming.

Of course not! The point isn't that Forth is better than any other language
because of these features; the point is simply that Joy has a lot to learn
from Forth. I think we can both agree on that; Joy also has a lot to learn
from Prolog.

>> Points 1..5 are of course incomplete and superficial. But they do
>> suggest that whatever cross-fertilisation there might be between
>> Forth and Joy it will not be due to the common postfix notation.

>I'm not sure I agree.

I'm not sure I really understand, either. I had expected that the
commonalities would be useful.

>Forth programs share many simple words
>with Joy programs
>(e.g. swap, dup, roll and so forth (haha, again), and both
>languages make very
>light use to symbolic names for values. I suspect that an
>algorithm expressed in both langauges will look quite similar.

Essentially, yes. Although they also have a lot of differences :-).

>I think there is much to be gained by Joy from looking at
>complex problems
>solved in forth and asking how it was done using only the
>stack. I find the
>structure of my Joy programs often disappears in a sea of dups
>and swaps: how
>to forth programmer avoid this? What abstractions do they use
>to express algorithms?

The main abstraction is function definition. If your structure is
disappearing, you want to rethink how you're calling your functions; often,
a little reordering of the computation makes the swaps go away, and when the
doesn't work it usually helps to refactor (make some words do a little more
or a little less, and change their names to match).

When worst comes to worst, you can start moving the swaps and such *into*
the words which need them; this at least hides the complexity, and leaves
your main algorithm clear.

A good average word definition length is about 40 characters. If your words
are all shorter than a line and are each followed by a brief test (which is
run at compile-time), there will be no bugs in them. ;-)

>> In the reverse direction, and independent of postfix
>> notation, here are some projects:

>> b) Examine the desirability of adding "CREATE..DOES.." to Joy.
>> This might be in tandem with a) or quite independently.

>I've got a knee-jerk reaction to this: it's a really, really
>bad idea. It makes the semantics of a program undecidable

Um... The semantics of programs are undecidable, according to Rice's
theorem. What are you talking about?

>with the
>following consequences:
>optimisation becomes really difficult; programs become
>difficult to debug;
>reasoning about the program is almost impossible; a true
>compiler would be
>handicapped; the semantics of already extant code could be changed.

Again, I have no idea what you're talking about. I've used CREATE-DOES> a
_lot_, and I've always found it an IMMENSE help.

>Moreover, why would it be useful? Joy already allows programs
>to be constructed and deconstructed on the fly.

First of all, CREATE-DOES> has nothing to do with constructing and
deconstructing programs. Did you think it does? If so, that does explain
your reaction to it.

Second, Joy's current method of constructing and deconstructing programs
leaves a LOT to be desired. We've talked about that in the past; the
problem is that quotations make optimization a LOT more complicated, and
crate a tree structure which can really block the reading of otherwise
simple code.

>> c) Investigate the power of macros. For text macros a useful starting
>> point would be the unix macro preprocessor m4. For syntax macros
>> (in Joy itself) some extensions (presumably 2.) are likely to be
>> necessary.

>A pre-processor, on the other hand, is probably useful. Joy
>already has it to
>some extent: the top level scanner changes [...] into a list
>and {...} into a
>set etc, and the == notation is pretty close to a macro anyway.

>I'm not sure what you mean by "syntax macros".

I believe he's referring to macros which are sensitive to the syntax of the
language (so that, for example, when you ask for "the next word in the
source stream", if the next word is actually the start of a quotation you'll
get the entire quotation instead of simply the next blank-delimited token).

m4 is a VERY bad choice. If you want to get fancy with parsing, take a look
at Rebol (www.rebol.com, see the 'parsing' section of the manual), or at the
Forth LL parser which is currently being developed on comp.lang.forth.
Those parsers fit right into the language.

Another thing Joy should consider from Forth is IMMEDIATE words; that is,
words which act as soon as they're seen (instead of being compiled). In
Forth, [ brackets ] are used in almost the opposite way from how they're
used in Joy: in Joy, brackets mean that the contents are being VERY compiled
(they're compiled into another word). In Forth, brackets escape from
compilation to allow you to do something immediately (at compile-time).

>Martin Young working for STMicroelectronics at `(o)_(o)'

-Billy

Martin Young — 2000-08-21 19:11:05

On Aug 21, 10:58am, wtanksley@... wrote:
> Subject: RE: [stack] Forth/Joy cross fertilization.
>
> From: Martin Young [mailto:martin.young@...]
> >On Aug 21, 2:37pm, phimvt@... wrote:
>
> >> 4. Manipulating the symbol table. This is quite different
> >> from 2. and deserves separate discussion. Forth can treat the symbol
> >> table like any other data structure. No other language does it to the
> >> same extent.
>
> >Again, in the case of Prolog, the programmer has complete
> >control over the symbol table.

Prolog programs can be deconstructed down to rules, terms, atoms and atoms'
constituent characters. They can also be reconstructed from the same elements.
Admitedly it doesn't have a symbol table in the sense of a simple mapping from
symbolic names to program code but there are no symbols in Prolog source which
aren't accessable to the executing program itself.

> CREATE defines a new word with no action (except to return the address of
> its data field, which is unallocated). DOES> modifies the last CREATE word
> to do some other action with that address.
>
> >I'm starting to sound obsessed: Prolog allows the programmer
> >to add to the program in this manner.
>
> Again, how? This doesn't sound AT ALL like the Prolog I learned.

Prolog programs consist exclusively of rules contained in a database. The
database is visible to programs and can be manipulated in arbitrary ways at any
time - any action can be associated with any rule. The program can be trimmed,
augmented or simply changed.

I appolgise for side-tracking the discussion - it really doesn't matter whether
(or not) Prolog can do what forth does.

I really don't understand your description of the forth words. My knowledge of
forth is based on what I learned about fig-Forth and forth-83, so I'm probably
well out of date.

I thought that CREATE creates a new symbolic name for a sub-program but leaves
the sub-program itself undefined, or rather it defines it as a trivial program
which simply returns an address specific to itself. DOES> binds a sub-program
to the most recently CREATEd symbolic name. This happens at run-time. Is this
correct?

What this actually gets you is a means of defining new words and adding them to
the symbol table, in terms of pre-existing ones, at run-time.

If I've misunderstood (again), what /does/ the CREATE/DOES> thing provide?

> The main abstraction is function definition. If your structure is
> disappearing, you want to rethink how you're calling your functions; often,
> a little reordering of the computation makes the swaps go away, and when the
> doesn't work it usually helps to refactor (make some words do a little more
> or a little less, and change their names to match).
>
> When worst comes to worst, you can start moving the swaps and such *into*
> the words which need them; this at least hides the complexity, and leaves
> your main algorithm clear.
>
> A good average word definition length is about 40 characters. If your words
> are all shorter than a line and are each followed by a brief test (which is
> run at compile-time), there will be no bugs in them. ;-)

Indeed. This is all good stuff. Functional programming languages generally
provide a library of higher order functions to hide the complexity in a
standard way. Joy could usefully learn what HoF-esque constucts forth
programmers have found useful over the years.

> >> In the reverse direction, and independent of postfix
> >> notation, here are some projects:
>
> >> b) Examine the desirability of adding "CREATE..DOES.." to Joy.
> >> This might be in tandem with a) or quite independently.
>
> >I've got a knee-jerk reaction to this: it's a really, really
> >bad idea. It makes the semantics of a program undecidable
>
> Um... The semantics of programs are undecidable, according to Rice's
> theorem. What are you talking about?

I mean if I define add like this

add == +

Then I know the semantics of

1 2 add

because I can statically resolve the word "add" to the primitve addition
operation. If I allow the word "add" to be defined at runtime, I can't
reliably resolve a program to well-understood primitives in this way. In fact,
if I allow strings from the input to affect the definitions of words then I
can't reliably examine anything other than un-redefinable primitives.

> >with the
> >following consequences:
> >optimisation becomes really difficult; programs become
> >difficult to debug;
> >reasoning about the program is almost impossible; a true
> >compiler would be
> >handicapped; the semantics of already extant code could be changed.
>
> Again, I have no idea what you're talking about. I've used CREATE-DOES> a
> _lot_, and I've always found it an IMMENSE help.

Sorry, I was unclear. It is undoubtedly very helpful to the programmer but a
pain for automatic program analysis.

A compiler to native code (rather than forth's compilation to pointers to
words) needs to know what each word means before the program executes. If a
word may be redefined at some point then it must include some run-time checking
code.

Given the words:

sub == swap -
sac == swap sub *

An optimiser could note that we could "inline" sub thus:

sac == swap sawp - *

And then eliminate the repeated swap. If "sub" may be redefined during
execution this optimisation is not possible.

I know that forth partially overcomes this (and "the semantics of already
extant code..." point) by binding symbolic names to programs at compilation
time but I remain unconvinced that this is a Good solution for a Joy-like
langauge.

My assertion about difficulty of debugging is based on experience of debugging
C++ programs where operators have been overloaded: it's hard to tell what the
program is actually going to do.

> >Moreover, why would it be useful? Joy already allows programs
> >to be constructed and deconstructed on the fly.
>
> First of all, CREATE-DOES> has nothing to do with constructing and
> deconstructing programs. Did you think it does? If so, that does explain
> your reaction to it.

I was under the impression the CREATE-DOES> allows new (named) programs to be
constructed from a sequence of other named programs. My point was that Joy
allows new (unnamed) programs to be constructed from a sequence of other named
(or unnamed) programs.

> Second, Joy's current method of constructing and deconstructing programs
> leaves a LOT to be desired. We've talked about that in the past; the
> problem is that quotations make optimization a LOT more complicated, and
> crate a tree structure which can really block the reading of otherwise
> simple code.

I find myself on the other side of that position. I think Joy's anonymous
quotations are it's most powerful tools for program clarification, and that
they can be efficiently implemented. I have little evidence of this - it's
simply an assertion on my part.

> m4 is a VERY bad choice.

Agreed. Eugh!

> If you want to get fancy with parsing, take a look
> at Rebol (www.rebol.com, see the 'parsing' section of the manual), or at the
> Forth LL parser which is currently being developed on comp.lang.forth.
> Those parsers fit right into the language.

Okay, I admit it. I'm incapable of not mentioning it at least twice in each
posting. Prolog has a lovely integrated grammar notion too.


--
Martin Young working for STMicroelectronics at `(o)_(o)' The fat wise /
1000 Aztec West, Almondsbury, Bristol, BS32 4SQ. ( V ) owl eats only >
+44 1454 462 523 `v' Martin.Young@... `.___,' clean mice. /
_(_)_ -="==="=============='

wtanksley@bigfoot.com — 2000-08-21 22:59:55

From: Martin Young [mailto:martin.young@...]
>On Aug 21, 10:58am, wtanksley@... wrote:
>> From: Martin Young [mailto:martin.young@...]
>> >On Aug 21, 2:37pm, phimvt@... wrote:

>> >Again, in the case of Prolog, the programmer has complete
>> >control over the symbol table.

>Prolog programs can be deconstructed down to rules, terms,
>atoms and atoms'
>constituent characters. They can also be reconstructed from
>the same elements.
> Admitedly it doesn't have a symbol table in the sense of a
>simple mapping from
>symbolic names to program code but there are no symbols in
>Prolog source which
>aren't accessable to the executing program itself.

I think I see what you're saying. Okay.

>> CREATE defines a new word with no action (except to return
>> the address of
>> its data field, which is unallocated). DOES> modifies the
>> last CREATE word
>> to do some other action with that address.

>I really don't understand your description of the forth words.
> My knowledge of
>forth is based on what I learned about fig-Forth and forth-83,
>so I'm probably well out of date.

No, they still act the same way. Your memory is just a bit wrong :-).

>I thought that CREATE creates a new symbolic name for a
>sub-program but leaves
>the sub-program itself undefined, or rather it defines it as a
>trivial program which simply returns an address specific to itself.

Essentially correct, although I don't know why you would say "sub-program"
instead of "word" or "function".

>DOES>
>binds a sub-program
>to the most recently CREATEd symbolic name. This happens at
>run-time. Is this correct?

Precisely, although in Forth "run-time" usually happens at compile-time.

>What this actually gets you is a means of defining new words
>and adding them to
>the symbol table, in terms of pre-existing ones, at run-time.

No. It gives you a means of CREATEing symbols with associated data and
actions at any time (compile-time is the best time to do that, but runtime
is possible). The actions themselves are NOT constructed at runtime;
they're constructed only at compile time.

>If I've misunderstood (again), what /does/ the CREATE/DOES>
>thing provide?

Smart data, mainly.

>Indeed. This is all good stuff. Functional programming
>languages generally
>provide a library of higher order functions to hide the complexity in a
>standard way. Joy could usefully learn what HoF-esque constucts forth
>programmers have found useful over the years.

What does HoF stand for?

Forth programmers seem to tend to be leery of huge libraries. They MUCH
prefer having the source available and modifiable; if they decide to
refactor, they often choose to refactor into the library. (At least the
first few versions of the library, until the library authors admit that
their first design wasn't perfect.)

>> >> b) Examine the desirability of adding "CREATE..DOES.." to Joy.
>> >> This might be in tandem with a) or quite independently.

>> >I've got a knee-jerk reaction to this: it's a really, really
>> >bad idea. It makes the semantics of a program undecidable

>> Um... The semantics of programs are undecidable, according to Rice's
>> theorem. What are you talking about?

>I mean if I define add like this
>add == +
>Then I know the semantics of
>1 2 add

>because I can statically resolve the word "add" to the
>primitve addition
>operation. If I allow the word "add" to be defined at runtime, I can't
>reliably resolve a program to well-understood primitives in
>this way. In fact,
>if I allow strings from the input to affect the definitions of
>words then I
>can't reliably examine anything other than un-redefinable primitives.

As you now know, create-does> has absolutely nothing to do with that.

However, CREATE by itself points out that Forth words _can_ create new
symbols (any of the other definition words can do the same). This is
obviously risky, and is precisely what I'm sure Joy's == syntax was designed
to avoid.

>A compiler to native code (rather than forth's compilation to
>pointers to
>words)

Most Forths now ARE native-code. In fact, the simplest possible Forth
compiler is Chuck's Machine Forth, which emits ONLY native code.

> needs to know what each word means before the program
>executes. If a
>word may be redefined at some point then it must include some
>run-time checking code.

Nope -- you don't understand how Forth's dictionary works. When you
redefine a word -- well, let me give you an example. We start with the
usual definition of "+".

: test+ 3 4 + . ; ( displays "7" )
: + - ; ( redefines the word "+" to mean "-" )
3 4 + . (displays -1)
test+ (displays "7", because words don't change behavior unless you
explicitly change them)

Does this make sense?

Now, we have a new version of "+", but none of the old words which used to
use + care about that; they were written to use the old version, and that's
just what they do.

Not only is the old version's code still present, but its definition is as
well; we just can't see it. If you'd like to see it, do this:

FORGET +

Now the new definition is gone, and the old one is visible.

>I know that forth partially overcomes this (and "the semantics
>of already
>extant code..." point) by binding symbolic names to programs
>at compilation time

What? I'm disappointed. You knew that Forth wasn't broken that way, and
yet you asked me how anyone could use Forth if it were broken that way???
Why did you ask me? Don't make false statements which you KNOW are false!

>but I remain unconvinced that this is a Good solution for
>a Joy-like langauge.

An excellent question. I'm completely convinced that it's the best possible
solution for almost any type of language.

The alternative is to either completely disallow ALL redefinitions, or to
require all words to be re-compiled every time they're run. Joy takes the
first route: it's impossible to redefine a word, all you can do is shadow
it. Lisp takes the second: you can redefine words, and every word using a
word of that name also gets redefined.

The Lisp solution is CLEARLY ridiculous. The rare occasions where that sort
of thing is actually wanted are easily achivable by either of the other two
methods without the HUGE speed loss.

The Joy solution is not ridiculous, but it DOES carry the implicit
assumption that the dictionary is NEVER manipulable by the program. That's
fine for a toy language or a special-purpose language, but it's a real shame
for a general-purpose language.

>My assertion about difficulty of debugging is based on
>experience of debugging
>C++ programs where operators have been overloaded: it's hard
>to tell what the program is actually going to do.

True. Fortunately, Forth has no operators, and Joy only has a few.

>> >Moreover, why would it be useful? Joy already allows programs
>> >to be constructed and deconstructed on the fly.

>> First of all, CREATE-DOES> has nothing to do with constructing and
>> deconstructing programs. Did you think it does? If so,
>> that does explain your reaction to it.

>I was under the impression the CREATE-DOES> allows new (named)
>programs to be
>constructed from a sequence of other named programs. My point
>was that Joy
>allows new (unnamed) programs to be constructed from a
>sequence of other named (or unnamed) programs.

Every concatenative language allows programs to be constructed from
sequences of other programs. Named or otherwise. Adding or removing CREATE
won't change that.

>> Second, Joy's current method of constructing and
>> deconstructing programs
>> leaves a LOT to be desired. We've talked about that in the past; the
>> problem is that quotations make optimization a LOT more
>> complicated, and
>> crate a tree structure which can really block the reading of
>> otherwise simple code.

>I find myself on the other side of that position. I think
>Joy's anonymous quotations are it's most powerful tools for
>program clarification, and that
>they can be efficiently implemented. I have little evidence
>of this - it's simply an assertion on my part.

Now, I _like_ Joy's quotations, but they _do_ add a lot of syntax to the
language, and a lot of slowness, and they provide a real temptation to
obfusicate your code (i.e. they make words like 'ifte' look fun to write,
but they're TERRIBLE to read).

There are other tools which do a better job, much more simply.

>> If you want to get fancy with parsing, take a look
>> at Rebol (www.rebol.com, see the 'parsing' section of the
>> manual), or at the
>> Forth LL parser which is currently being developed on
>> comp.lang.forth. Those parsers fit right into the language.

>Okay, I admit it. I'm incapable of not mentioning it at least
>twice in each
>posting. Prolog has a lovely integrated grammar notion too.

I remember Prolog's ability to define infix operators and similar things;
however, I wouldn't call that a grammar, since it requires that you use
Prolog's own grammar. Both Rebol and Forth use full LL parsers.

>Martin Young working for STMicroelectronics at `(o)_(o)'

-Billy

Martin Young — 2000-08-22 10:48:13

On Aug 21, 3:59pm, wtanksley@... wrote:

> >If I've misunderstood (again), what /does/ the CREATE/DOES>
> >thing provide?
> Smart data, mainly.

Obviously I need to read Salman et al again.

> >Joy could usefully learn what HoF-esque constucts forth
> >programmers have found useful over the years.
>
> What does HoF stand for?

Higher order functions.

> Nope -- you don't understand how Forth's dictionary works. When you
> redefine a word -- well, let me give you an example. We start with the
> usual definition of "+".
[snip description]

> >I know that forth partially overcomes this (and "the semantics
> >of already
> >extant code..." point) by binding symbolic names to programs
> >at compilation time
>
> What? I'm disappointed. You knew that Forth wasn't broken that way, and
> yet you asked me how anyone could use Forth if it were broken that way???
> Why did you ask me? Don't make false statements which you KNOW are false!

I don't think my statement was false, and I'm not asserting that forth is
"broken", only that for a new langauge I personally wouldn't include such a
feature.

My concern is this: given a piece of source code, the same word may have
different actions associated with it at different times. The combination of
the compile-time/execution-time split and redefinition words would seem to make
it difficult to decide what each instance of a word actually does.

> The alternative is to either completely disallow ALL redefinitions, or to
> require all words to be re-compiled every time they're run. Joy takes the
> first route: it's impossible to redefine a word, all you can do is shadow
> it. Lisp takes the second: you can redefine words, and every word using a
> word of that name also gets redefined.
>
> The Lisp solution is CLEARLY ridiculous.

Agreed.

> The Joy solution is not ridiculous, but it DOES carry the implicit
> assumption that the dictionary is NEVER manipulable by the program. That's
> fine for a toy language or a special-purpose language, but it's a real shame
> for a general-purpose language.

I disagree. I don't think my choice of symbolic names should have any effect
at all on program semantics.

> >My assertion about difficulty of debugging is based on
> >experience of debugging
> >C++ programs where operators have been overloaded: it's hard
> >to tell what the program is actually going to do.
>
> True. Fortunately, Forth has no operators, and Joy only has a few.

Aren't most forth and joy words unary operators on a stack?

> >I was under the impression the CREATE-DOES> allows new (named)
> >programs to be
> >constructed from a sequence of other named programs. My point
> >was that Joy
> >allows new (unnamed) programs to be constructed from a
> >sequence of other named (or unnamed) programs.
>
> Every concatenative language allows programs to be constructed from
> sequences of other programs. Named or otherwise. Adding or removing CREATE
> won't change that.

They all do at the source level, by definiton, but I suggest that it's possible
to build a concatenative langauge which doesn't allow new programs to be built
during execution.

Naming new programs is sailing close to re-introducing lambda, no?

> Now, I _like_ Joy's quotations, but [snip]
> There are other tools which do a better job, much more simply.

Such as?

> I remember Prolog's ability to define infix operators and similar things;
> however, I wouldn't call that a grammar, since it requires that you use
> Prolog's own grammar. Both Rebol and Forth use full LL parsers.

Both vanilla Edinburgh and ISO Prologs have Definite Clause Grammer syntax in
their scanners. This automatically converts grammar rules into executable
Prolog. It's more like a built-in lex/yacc than a meta-language for Prolog.

I know forth has the ability to deal with words later in the input stream than
the current one. Is this what the LL parser is applied to? ...and Rebol does
the same? Cool.


--
Martin Young working for STMicroelectronics at `(o)_(o)' The fat wise /
1000 Aztec West, Almondsbury, Bristol, BS32 4SQ. ( V ) owl eats only >
+44 1454 462 523 `v' Martin.Young@... `.___,' clean mice. /
_(_)_ -="==="=============='