# ==

## John Carter — 2001-08-07 06:03:43

    There is one part of Joy that I'll admit I'm not comfortable with.

    This is quitely likely a failure on my part to understand...

    The == operator that assigns a name to "word" seems to stand apart and out

    of the paradigm of joy.

    Why is the == operator infix?

    Instead of...

      myword == this that the other;

    have

      [this that the other] myword ==

    Postscript has the notion of a stack of dictionaries parallel to the

    execution stack.

    A "def" or == stores the word into the dictionary currently on top of the

    dictionary stack.

    A reference is resolved by looking in the topmost dictionary, if it

    doesn't find it there, it looks in the next dictionary so on down until

    the bottom most dictionary of system primitives.

    So instead of the notion of a Joy word being a function of a stack

    returning a stack, it becomes a function of a stack and a stack of

    dictionaries returning a stack and a stack of dictionaries.

    Please enlighten me as to why this curiosity out of paradigm == exists

    within Joy, I'm confuzzled.

    Thank you,

    John Carter                             Phone : (64)(3) 358 6639

    Tait Electronics                        Fax   : (64)(3) 359 4632

    PO Box 1645 Christchurch                Email : john.carter@...

    New Zealand

    I'm becoming less and less convinced of humans as rational beings.

    I suspect we are merely meme collectors, and the reason meme is only

    kept on to help count our change.

## Jack Waugh — 2001-08-08 13:27:13

    Perhaps the answer is that == is not part of Joy proper, but part of

    Metajoy.

    Joy exists for discussion, not for practical programming, right?

    When we say something like

    copy-me == [dup cons] dup cons

    we just mean that when we say copy-me in the ensuing discussion, we

    mean [dup cons] dup cons.

    If you added postfix == (or :=) to the language, you'd be introducing

    something to the state besides the stack, which might destroy the

    purity of the langauge (of course, the I/O already destroys it, but

    we can ignore that for now and repair it if and when we want to make

    such use or discussion of Joy as raises any need to get serious about

    I/O).

## John Carter — 2001-08-08 22:50:15

    On Wed, 8 Aug 2001, Jack Waugh wrote:

     > Perhaps the answer is that == is not part of Joy proper, but part of

    > Metajoy.

    >

    > Joy exists for discussion, not for practical programming, right?

     As yet perhaps, but I have deep plans and dark plotches....

    Anything that has such a simple algebra on it has to, in the cosmic sense,

    has to be eminently more practical than any current language.

     > If you added postfix == (or :=) to the language, you'd be introducing

    > something to the state besides the stack,

     Yes, Postscript copes with this by having two stacks. The dict stack and

    the ordinary stack.

    The way I see the whole thing the primary value of Joy is that Algebra and

    the Rewrite rules. Anything that destroys that would be a crying shame in

    my view.

    Now == stands outside of Joy and hence is cannot be made part of the

    algebra and rewrite rules.

    Now what if we took things a step further and made == within the paradigm

    so we could have an algebra that operated on it?

    For those fragments of code that do not operate on the dictionary stack we

    are in exactly the state of innocence as in Joy code outside the LIBRA -

    END.

    Part of the reason for the simplicity of the Joy algebra compared to say an

    algebra on Scheme, is that a lambda expression that binds arguments to

    names becomes complex to reason about.  Something deep within the stack (a

    value) becomes bound to something at the top (a reference)

    A stack machine and name binding free nature of Joy localises cause and

    effect making it very simple to reason about small fragments of Joy.

    Now introducing name binding into Joy on a seperate dict stack would

    unfortunately reintroduce some, but not all of those complexities.

    And alternate would be a word stack. So instead of saying

    square == dup *;

    Or postcriptish...

    [dup *] "square" defun

    To remain in a purely Joyish mode one could simply treat the dictionary

    stack instead of as a stack of dictionaries as a stack of words.

    [dup *] word (moves the top of the execution stack to the top of the

    word stack.)

    Thereafter the operator "invokeword" would invoke the word currently

    on top of the word stack. You can add some primitives (dupword,

    swapword,...) to manage the wordstack.

    Still given the existence system primitives and the library functions

    I suspect the Postscriptish "stack of dictionaries" approach is more

    practical. (And is blessed by a an emminently pragmatic history of

    being a working solution.)

    I also suspect if the operators on the dictionaries are simple and

    direct enough a reasonable algebra for their behaviour may also be

    derived.

    John Carter                             Phone : (64)(3) 358 6639

    Tait Electronics                        Fax   : (64)(3) 359 4632

    PO Box 1645 Christchurch                Email : john.carter@...

    New Zealand

    I'm becoming less and less convinced of humans as rational beings.

    I suspect we are merely meme collectors, and the reason meme is only

    kept on to help count our change.

## Jack Waugh — 2001-08-10 13:56:39

    In re

     > Still given the existence system primitives and the library

     functions

     > I suspect the Postscriptish "stack of dictionaries" approach is more

    > practical. (And is blessed by a an emminently pragmatic history of

    > being a working solution.)

    >

    > I also suspect if the operators on the dictionaries are simple and

    > direct enough a reasonable algebra for their behaviour may also be

    > derived.

     You're proposing to have an environment where names get mapped to

    functions.  You would do that with a stack of dictionaries in

    addition to the operand stack.  Elsewhere participants in the forum

    spoke for polymorphism.  I see these things as relatable to each

    other, the environment and polymorphism.  In the imperative

    programming language Self, the application of a procedure to the

    system state involves setting up an environment, where names get

    mapped to operations (it is easy to imagine a functional subset of

    Self, in which we would say the environment maps function names to

    functions).  Environments in Self consist of _slots_.  Each slot maps

    from a name to an operation or a value.  A slot can be marked as

    _inheriting_.  If the interpreter does not find the name it's looking

    for in a given environment, it tries to delegate the operation to the

    definition in some ancestor that it finds by looking at the

    environments (objects) pointed to by the original environment's

    inheriting slots.  The current environment for execution inherits

    from the _receiver_ of the message currently being interpreted.  This

    inheritance between the receiver and the environment gives Self its

    namesake feature, that "foo" at the beginning of a command is

    equivalent to "self foo"; "self" is effectively implicit (as compared

    to Smalltalk, where it would have to be explicit).  I see similarity

    between Self's looking in the environment for a mapping, then in the

    receiver, then in its parents, and so on, and the stack of

    dictionaries in Postscript, where the interpreter looks in the top

    dictionary, then the next deeper dictionary in the stack, and so on.

    Of course Forth achieves a similar effect quite elegantly using its

    linked vocabularies.

    Would Joy have the algebraic properties you want if we extended it to

    permit programmable polymorphism, and a current envirionment, along

    lines such as the following?  There would be a way to cobble up a

    polymorphic value.  Such a value would contain _two_ mappings from

    names to functions.  I call them the _external map_ and the _internal

    map_.  Functions found in these maps we can call _methods_, borrowing

    from the jargon of object-oriented programming.

    When the interpreter sees a word in the stream it is executing, it

    wants to look up a function from the word.  There is a current

    environment in which the matching definition might appear.  Also, if

    the operand stack is not empty, the interpreter looks at the external

    map of the top element.  This may supply a match for the word the

    interpreter is trying to map.  In case both mappings supply matches,

    I'm not sure which should take precedence.

    Suppose the decision is to execute a method found in the external map

    of the polymorphic value found on top of the stack.  In that case,

    the interpreter must push the current environment on a separate stack

    for the purpose and make the _internal map_ of the top element of the

    operand stack become the current environment.  At this point we

    should or should not pop the top element off the operand stack; I'm

    not sure.  It's a matter of style.  If the convention is to pop it,

    it is not necessarily lost; it may be recoverable from its own

    internal map.  Now the interpreter executes the method using the new

    environmnet.  When the method finishes, the interpreter pops back the

    old environment from the environment stack.  Although this proposal

    and yours both involve a stack of dicitonaries, they differ in that

    yours would look down the stack on failing to find a match in the top

    dictionary.  Mine instead would look to the external map of the top

    stack element, so as to implement polymorphism.

    Typical values would inherit from (or be partly copied from) a root

    value that would provide in one or both of its maps the mappings from

    standard names such as "dup", to the interpreter primitives to

    provide the default behaviors for those names.  As in Smalltalk or

    Self, a special form would tell the compiler to compile in an

    invocation of an interpreter primitive.  Smalltalk uses numbers for

    these; Self uses names beginning with underlines.  Some values,

    intended to be _linear_, might override "dup" and "pop" (externally)

    in order to disallow them.  Hmm, either they'd also have to be

    jimmied to disallow the primitive dup and pop, or we'd have to give

    the external methods of the top stack element priority over the

    environment.  But I'm sure the environment should have priority for

    functions that don't use up the top stack element, at least, because

    an engineer would like to be able to design the interactions internal

    to a polymorphic value without fear of a name clash with some

    interlocutor's external baggage.

## Manfred von Thun — 2001-08-13 08:31:57

    On Fri, 10 Aug 2001, Jack Waugh wrote:

     > You're proposing to have an environment where names get mapped to

    > functions.  You would do that with a stack of dictionaries in

    > addition to the operand stack.  Elsewhere participants in the forum

    > spoke for polymorphism.  I see these things as relatable to each

    > other, the environment and polymorphism.  In the imperative

    > programming language Self, the application of a procedure to the

    > system state involves setting up an environment, where names get

    > mapped to operations (it is easy to imagine a functional subset of

    > Self, in which we would say the environment maps function names to

    > functions).  Environments in Self consist of _slots_.  Each slot maps

    > from a name to an operation or a value.

     I do not know anything about the Self language, but environments

    of course occur in any language in which there are named formal

    parameters and which on call take on the value of the actual

    parameter. See the Joy FAQ for why Joy does not have them.

    Note also that environments are different from the dictionary

    of name / body associations set up by definitions of functions

    and procedures, and different again from the state in imperative

    languages which is changed by assignment.

    [Other remarks about Self, Forth and Postscript]

     > Would Joy have the algebraic properties you want if we extended it to

    > permit programmable polymorphism, and a current envirionment, along

    > lines such as the following?  There would be a way to cobble up a

    > polymorphic value.  Such a value would contain _two_ mappings from

    > names to functions.  I call them the _external map_ and the _internal

    > map_.  Functions found in these maps we can call _methods_, borrowing

    > from the jargon of object-oriented programming.

     Joy would no longer be functional if it had a state.

    All functional languages have the substitutional property.

    But Joy does not even have an environment as the other

    functional languages do. Hence substitution does not involve

    complicated beta-reduction but simple textual substitution.

    I'll look at Self some time soon.

      - Manfred

## Jack Waugh — 2001-08-13 15:49:22

    So Manfred von Thun and John Carter are in disagreement about whether

    having a stack of dictionaries in addition to the operand stack would

    remove desirable mathematical properties?

## John Carter — 2001-08-14 03:05:00

    On Mon, 13 Aug 2001, Jack Waugh wrote:

     > So Manfred von Thun and John Carter are in disagreement about whether

    > having a stack of dictionaries in addition to the operand stack would

    > remove desirable mathematical properties?

     Firstly, I am fully in agreement that having operators that change the

    definitions of the words destroys the algebra for fragments including that

    operator.

    Before and after dictionary fiddling operators you are in _exactly_ the

    same state of grace as on either side of a LIBRA..END block.

    In Joy the process of fiddling the environment (LIBRA...END), and the

    process of execution is kept seperated.

    However, an algebra including operations on a dictionary would be

    considerably more complex, but not undoable.

    My point then is if LIBRA..END and == destroy the algebra for fragments

    crossing them anyway, why not make == fit uniformly with the postfix

    paradigm?

    In dynamic languages like Scheme and postscript defun's can be created at

    run time.

    Joy is fish and fowl. The LIBRA..END creates a compile time

    definition of the defun's.

    Unfortunately a large part of the appeal (to me at least) of a language

    like Joy is the reflexiveness of it. Creating/Analysing Joy programs with

    Joy programs is truly easy. Having crafted a complex word with a Joy

    program, one is permitted the convenience of saving for later use.

    Note the difference.

    Defuns (==) name words.

    Scheme like lambda's name parameters.

    Both destroy the Joy algebra.

    Scheme-like lambda's irredeemably complexify the algebra at a fine level.

    Defun's change the algebra when they occur, but one can deduce the

    properties of the defun and and there after use those proerties within the

    algebra.

    John Carter                             Phone : (64)(3) 358 6639

    Tait Electronics                        Fax   : (64)(3) 359 4632

    PO Box 1645 Christchurch                Email : john.carter@...

    New Zealand

    I'm becoming less and less convinced of humans as rational beings.

    I suspect we are merely meme collectors, and the reason meme is only

    kept on to help count our change.

## Manfred von Thun — 2001-08-14 09:57:21

    On Tue, 14 Aug 2001, John Carter wrote:

     > Firstly, I am fully in agreement that having operators that change the

    > definitions of the words destroys the algebra for fragments including that

    > operator.

     Exactly so.

     > In Joy the process of fiddling the environment (LIBRA...END), and the

    > process of execution is kept seperated.

     "fiddlinng the _definitions_" yes. In the technical sense of

    "environment", lambda calculus based languages have it,

    but Joy does not. (See the FAQ "What is an environment")

     > However, an algebra including operations on a dictionary would be

    > considerably more complex, but not undoable.

     If "dictionary" means environment (binding of formals to actuals)

    then any lambda calculus based language does it, and

    the algebra is well known - it is beta reduction in the lambda calculus.

    As you say, it is considerably more complex than the simple

    textual substitution in Joy.

     > My point then is if LIBRA..END and == destroy the algebra for fragments

    > crossing them anyway, why not make == fit uniformly with the postfix

    > paradigm?

     At the end of the FAQ, see "Further Frequently Asked Questions"

    which I have added only a couple of hours ago.

     > In dynamic languages like Scheme and postscript defun's can be created at

    > run time.

     I don't know much about Postscript, but I know a bit about

    Scheme even if I have written next to nothing in it. If I read you

    correctly, you are saying that I can define (in the ordinary way)

    a function which, when called will define (in an extraordinary way)

    a function which when called do what it was defined to be?

    Excuse the exact syntax, but it would be something like

      (defun ordinary (x)

          (if (< x 5)

    	(defun extraordinary (a b) (+ a b))

    	(defun extraordinary (a b) (* a b)) ) )

    Now after the call  (ordinary 10)

    as the body of ordinary is executed at run time,

    the second definition of extraordinary should be entered.

    Now the further call (extraordinary 3 4)  should produce  12

    I have never seen anything like that in Scheme programs

    (or in Lisp programs). Is this what you meant? If so,

    can you give a reference, because I must then clear up my

    misunderstanding of Scheme (or Lisp).

     >

    > Joy is fish and fowl. The LIBRA..END creates a compile time

    > definition of the defun's.

     Exactly so. I thought that it is like almost all other languages

    in that respect.

     > Unfortunately a large part of the appeal (to me at least) of a language

    > like Joy is the reflexiveness of it. Creating/Analysing Joy programs with

    > Joy programs is truly easy. Having crafted a complex word with a Joy

    > program, one is permitted the convenience of saving for later use.

     I think that the reflectiveness is quite orthogonal to the ability

    to define things ("words", literals, operators, combinators).

    A language without definitions would be difficult to use.

     > Note the difference.

    >

    > Defuns (==) name words.

    >

    > Scheme like lambda's name parameters.

    > Both destroy the Joy algebra.

     The environment (formal/actual parameter correspondence or association)

    created at call makes beta reduction in Scheme and other lambda calculus

    languages hard. None of that in Joy.

    But ordinary definitions in Joy do not destroy the algebra at all.

    If anything, they create extensions to the algebra of the primitives.

    See below.

     > Scheme-like lambda's irredeemably complexify the algebra at a fine level.

     Exactly so.

     > Defun's change the algebra when they occur, but one can deduce the

    > properties of the defun and and there after use those proerties within the

    > algebra.

     I would not have said "change", but what you then continue to say is

    exactly right: After the definition (or: within the scope of the

    definition)

             name  ==   b o d y               (* that is the body *)

    for any programs P and Q,

            P  name  Q    ==    P  b o d y Q

    That's Joy for you.

      - Manfred