# 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.  /

                       _(_)_                             -="==="=============='