# Re: [stack] YACL - Yet Another Concatenative Language

## sa@dfa.com — 2003-07-02 19:42:22

    there's another way to look at this behavior.  if you want to avoid

    the appearance of naked operators on the stack, you can either quote

    them in some way before pushing them, or let them appear and then

    re-evaluate the stack by pushing its elements one-at-a-time onto the

    empty stack.  you keep doing that until all the stack-items are

    "inert"; i.e., re-evaluation leaves the stack unchanged.

    in cK i provide this as an alternate evaluation behavior ('1 naked').

    e.g.

           1 naked

           [2 3 +] unstack

         5

    the core of the interpreter is the 'a' function, which takes a stack

    x and a single item y to evaluate and returns a new stack:  if y is

    an operator apply y to x else append y to x:

         a:{:[7=4:y;y x;x,,y]}

    to get the relentlessly self-pushing behavior:

         a:{:[7=4:y;()_f/y x;x,,y]}

    i.e. if y is an operator, apply it to the stack, and then keep applying

    the current function (_f) to it until you get the same result

    twice-in-a-row.

    this uses the 'converge' adverb/combinator of k/cK.

    since the problem case is in some sense "pathological", or at least rare,

    you wind up paying a tiny cost for the superfluous appends.

    under this regime, you get some pretty spectacular chain-reactions:

      1 naked

      -30 trace

      [[2 3 + pop] unstack] unstack

                                            [[2 3 + pop] unstack]

                [[2 3 + pop] unstack]       unstack

                                            [2 3 + pop]

                          [2 3 + pop]       unstack

                                            2

                                    2       3

                                  2 3       +

                                            5

                                    5       pop

    btw, since today is my birthday, and my age is mathematically, if not

    - alas - biologically reversible, i can announce the k implementation

    of brent's brain-twisting (but morally uplifting) language, befreak:

         http://www.nsl.com/papers/befreak.htm

                        phimvt@...

                        obe.edu.au               To:     concatenative@yahoogroups.com

                                                 cc:

                        07/01/03 10:42 PM        Subject:     [stack] YACL - Yet Another Concatenative Language

                        Please respond to

                        concatenative

     On Sun, 29 Jun 2003, Brent Kerby wrote:

    [...]

    > Good point. Joy's semantics with these unquoted operators has

    always baffled

    > me a bit. As I see it, operators like 'first' that pull lists apart fall

    > into a different class from more well-behaved combinators like 'swap',

    > 'dup', 'cons', 'cat', 'tack', etc.

    Example: In a particular family there are children [peter paul mary]

    and pets [dup dip pop] and kitchen tables [square round] and for

    the next month guests will be expected on the dates [3 8 17 22 29].

    In each case, to get the first item of the respective lists you

    use the 'first' operator. This will always work, even though 'dup'

    is a Joy builtin and 'square' is defined in a library. It will

    continue to work even if in the future 'peter' becomes a builtin

    or is defined in a library. All pretty regular, I think.

    [...]

    > So then, here's another possible way of solving your problem, other

    than

    > using an escape ... When we do "[+] first", then there is something on

    the

    > stack, call it +' .

    This postfix quote may be OK for the program, but what ends up on the

    stack should not be this quoted thing. One would want to be able to

    cons the top item into another list/quotation, maybe to be executed,

    maybe to be written. If the quoted thing ends up on the stack, then

    you need another dequote operation to be able to cons it into something

    else.

    One may very well want a unary quotation operator, say your postfix

    quote or a prefix Q. Note that this is a different sense of 'unary',

    not the sense in which 'rest', 'not', 'square' are (semantically)

    unary. Whatever the exact notation used, "+'" or "Q+" or "Q +" will

    be an atom which pushes the (binary) addition operator, or whatever

    the argument of the "'" or "Q" is. So in general,

        [foo] first  ==  foo'  ==  Q foo

    But the "'" or "Q" cannot stand on their own, they need an atom

    as an argument to become syntactically correct. In the grammar

    there would need to be another production:

        factor  ::=  "Q" factor

    This raises the question of what  'Q  Q  Q  foo' should mean.

    Perhaps the same as 'Q foo'. The implementation of Q would not

    be quite as trivial as it may look, even just for single Q's,

    because Q is not just another atom. Is it worth it ?

    [...]

    >                    (Perhaps it would be handy for Joy to have syntax

    > directly for unquoted operators so they don't have to be constructed

    > sneakily using 'first').

    You are not persuaded? You don't like sneaky Joy? You want Yacl :

        YACL   =   Yet Another Concatenative Language

    Every syntactically correct Joy program is also a syntactically

    correct Yacl program. The difference is in the semantics. What

    in Joy are called operators and combinators are exactly like

    literals in Yacl: when executed they result in a push operation.

    So after the execution of

        5  dup  *

    the stack will contain three items: '*' on top, 'dup' second,

    and '5' third. (So execution is a bit like reversal, if you think

    of the stack as a list). Quotations are left untouched, so

        [1 2]  [foo bar]  concat

    result in a stack of three items, 'concat' on top, '[foo bar]'

    second, '[1 2]' third.

    What is the point, you ask? Well, everything is treated as if it

    were quoted, either as '[foo] first' or as "foo'" or as "Q foo"

    So there is no need for the unary quotaion operator in Yacl.

    But how does Yacl do any computation, like the square or 5 ?

    Easy: There is another atom, not a unary operator, called 'E'

    for 'execute'. The square of 5 is computed by either

            5  dup  E  *  E

    or      5  E  dup  E  *  E

    Semantically the E executes the top single item on the stack in

    the same way that Joy would. If that item is an operator or combinator

    E will execute it as such. If that item is a literal such as 5,

    then E will push it on the stack. So for literals x, x E  == x.

    One could define such an E in Joy as  E == [] cons i, of course,

    and the little joy-in-joy uses something like that. But E in Joy

    would be rarely used, in Yacl it is essential. One more example:

        [1 2 3 4]  [dup E * E]  map E     ==>    [1 4 9 16]

    In the now very exceptional case where you actually want the E

    on top of the stack you would need  '[E] first E', unless you

    want to introduce a unary quotation operator:  "E'" or "Q E".

    End-of-Yacl-manual

    Thank you all, I really enjoy (!) these discussions.

      - Manfred

    To unsubscribe from this group, send an email to:

    concatenative-unsubscribe@egroups.com

    Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

## Tanksley, William D. Jr. — 2003-07-03 15:09:56

    From: sa@... [mailto:sa@...]

     >there's another way to look at this behavior.  if you want to avoid

    >the appearance of naked operators on the stack, you can either quote

    >them in some way before pushing them, or let them appear and then

    >re-evaluate the stack by pushing its elements one-at-a-time onto the

    >empty stack.  you keep doing that until all the stack-items are

    >"inert"; i.e., re-evaluation leaves the stack unchanged.

     In my opinion, the real problem here is the confusion in Joy between

    delisting and execution, and correspondingly between enlisting and

    quotation.

    This confusion becomes more difficult when you add array-processing to the

    language. While playing with cK I realised why Joy's quotation makes me

    uncomfortable, and what I'm going to do about it. No need to change Joy, of

    course, but my language will distinguish between quotation and enlistment --

    and more importantly, between delistment and execution. My equivalent to the

    'i' combinator will take a scalar as an argument, not a list. If you want to

    execute a list, you iterate over its elements using the stack as the

    "accumulator". If the list happens to be quoted, this is exactly equivalent

    to Joy's 'i' combinator.

    Quotation will be handled in a similar manner to Lisp; a prefix ' operator

    can appear before defined symbols or literals (including literal lists, in

    which case everything in the list is quoted). However, lack of quotation

    will mean that the words appearing in the [] will be executed, and then the

    resulting stack will be enlisted.

    The reason I'm doing this is simply that it makes so much more sense in an

    array-manipulation language. All the old functionality is still available,

    but it now becomes possible to more precisely control how execution happens

    in lists.

    But I think it also helps when you consider the theory of the language, too.

    -Billy

## stevan apter — 2003-07-03 15:54:11

    i've read this several times, and i'm still having trouble

    visualizing the proposal (probably because i spent the previous

    hour immersed in the adventures of brad christiansen -- e.g.

    http://www.quatloos.com/brad-c/elvis.htm.  careful!  this

    is the email equivalent of those famous inverting prism

    spectacles you encountered in psych 101.)

    perhaps you can provide a few examples to illustrate the

    language?  (and send along a bank account # into which i can

    wire a donation to the project.)

     ----- Original Message -----

    From: "Tanksley, William D. Jr." <william.d.tanksley.jr@...>

    To: <concatenative@yahoogroups.com>

    Sent: Thursday, July 03, 2003 11:09 AM

    Subject: RE: [stack] YACL - Yet Another Concatenative Language

    > From: sa@... [mailto:sa@...]

    >

    > >there's another way to look at this behavior.  if you want to avoid

    > >the appearance of naked operators on the stack, you can either quote

    > >them in some way before pushing them, or let them appear and then

    > >re-evaluate the stack by pushing its elements one-at-a-time onto the

    > >empty stack.  you keep doing that until all the stack-items are

    > >"inert"; i.e., re-evaluation leaves the stack unchanged.

    >

    > In my opinion, the real problem here is the confusion in Joy between

    > delisting and execution, and correspondingly between enlisting and

    > quotation.

    >

    > This confusion becomes more difficult when you add array-processing to the

    > language. While playing with cK I realised why Joy's quotation makes me

    > uncomfortable, and what I'm going to do about it. No need to change Joy, of

    > course, but my language will distinguish between quotation and enlistment --

    > and more importantly, between delistment and execution. My equivalent to the

    > 'i' combinator will take a scalar as an argument, not a list. If you want to

    > execute a list, you iterate over its elements using the stack as the

    > "accumulator". If the list happens to be quoted, this is exactly equivalent

    > to Joy's 'i' combinator.

    >

    > Quotation will be handled in a similar manner to Lisp; a prefix ' operator

    > can appear before defined symbols or literals (including literal lists, in

    > which case everything in the list is quoted). However, lack of quotation

    > will mean that the words appearing in the [] will be executed, and then the

    > resulting stack will be enlisted.

    >

    > The reason I'm doing this is simply that it makes so much more sense in an

    > array-manipulation language. All the old functionality is still available,

    > but it now becomes possible to more precisely control how execution happens

    > in lists.

    >

    > But I think it also helps when you consider the theory of the language, too.

    >

    > -Billy

    >

    >

    > To unsubscribe from this group, send an email to:

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

    >

    >

## Tanksley, William D. Jr. — 2003-07-03 16:39:49

    From: stevan apter [mailto:sa@...]

     >i've read this several times, and i'm still having trouble

    >visualizing the proposal

     No suprise -- although I apologise. I've written that message three times

    and had it bounce twice, so I was getting a little incoherent.

    At the most primitive level, I purpose to remove Joy's current concept of

    "quotations" by redefining all words which currently take a quotation into

    words which take a function on the stack. I will, of course, provide syntax

    to place a function as a literal (onto the stack, into a list, or anywhere

    else a literal can go).

    The reasons I want to do this are many -- Joy's quotations have irritated me

    on a theoretical level for a long time -- but the one you'll probably find

    most understandable is that I want 'i' to be useful when iterating through

    lists. Right now 'i' is defined on lists, so cK's iteration isn't usable on

    it.

    The basic idea has been percolating in my mind for a long time, but it

    really came to the forefront when you explained k8 to me. I realised that

    Joy just couldn't handle that interpretation of transposition (sorry,

    Joy-list people; this is an inside reference from a private email, and you

    aren't meant to understand it), but that my earlier language design could

    quite easily.

    This made me put some more thought into my earlier discomfort with Joy's

    quotations, and what I finally came up with was that I was more comfortable

    with execution as an atomic operation.

     >(and send along a bank account # into which i can

    >wire a donation to the project.)

     :-)

    -Billy

## stevan apter — 2003-07-03 17:29:56

    ----- Original Message -----

    From: "Tanksley, William D. Jr." <william.d.tanksley.jr@...>

    To: <concatenative@yahoogroups.com>

    Sent: Thursday, July 03, 2003 12:39 PM

    Subject: RE: [stack] YACL - Yet Another Concatenative Language

    > From: stevan apter [mailto:sa@...]

    >

    > >i've read this several times, and i'm still having trouble

    > >visualizing the proposal

    >

    > No suprise -- although I apologise. I've written that message three times

    > and had it bounce twice, so I was getting a little incoherent.

    >

    > At the most primitive level, I purpose to remove Joy's current concept of

    > "quotations" by redefining all words which currently take a quotation into

    > words which take a function on the stack. I will, of course, provide syntax

    > to place a function as a literal (onto the stack, into a list, or anywhere

    > else a literal can go).

    >

    > The reasons I want to do this are many -- Joy's quotations have irritated me

    > on a theoretical level for a long time -- but the one you'll probably find

    > most understandable is that I want 'i' to be useful when iterating through

    > lists. Right now 'i' is defined on lists, so cK's iteration isn't usable on

    > it.

    ok, let's see if this matches what you're thinking.

        2 3 +

      5              still works, right?

        2 [3 +]

      2 [3 +]

        2 [3 +] )    ) is "enclose" - makes a function from a list

      2 {3 +}        {} is literal function definition

        i

      5

        {3 +} (      ( is "disclose" - makes a list from a function

      [3 +]

        [+] )

      {+}

        [3 +] ) )

      {{3+}}

        [3 +] (

      error?

    tolerant:

        {2}

      2

        2 )

      2

        2 (

      2

    >

    > The basic idea has been percolating in my mind for a long time, but it

    > really came to the forefront when you explained k8 to me. I realised that

    > Joy just couldn't handle that interpretation of transposition (sorry,

    > Joy-list people; this is an inside reference from a private email, and you

    > aren't meant to understand it), but that my earlier language design could

    > quite easily.

    i think you're right.

    >

    > This made me put some more thought into my earlier discomfort with Joy's

    > quotations, and what I finally came up with was that I was more comfortable

    > with execution as an atomic operation.

    >

    > >(and send along a bank account # into which i can

    > >wire a donation to the project.)

    >

    > :-)

    >

    > -Billy

    >

    >

    > To unsubscribe from this group, send an email to:

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

    >

    >

## Tanksley, William D. Jr. — 2003-07-03 18:29:14

    From: stevan apter [mailto:sa@...]

     >ok, let's see if this matches what you're thinking.

    >    2 3 +

    >  5              still works, right?

     Right.

     >    2 [3 +]

    >  2 [3 +]

     Almost -- I'm using a different syntax to quote, so you could write this as:

      2 '[3 +]

    or:

      2 [3 '+].

     >    2 [3 +] )    ) is "enclose" - makes a function from a list

    >  2 {3 +}        {} is literal function definition

    >    i

    >  5

     My initial language won't have "enclose" nor literal function definition,

    but it's possible, yes. Either would probably be simple in cK.

     >    {3 +} (      ( is "disclose" - makes a list from a function

    >  [3 +]

     I definitely won't have disclose.

     >    [3 +] ) )

    >  {{3+}}

     Double enclose would be a no-op for me, if I implemented it. You can

    definitely enlist it and then enclose the result, though.

    I think you've got the basic idea, although all your examples are things I

    won't be implementing (because I don't want to bother with enclose for now,

    and I don't think disclose is worth the effort). Some other examples:

      '[2 3 +] unlist

    2 3 '+

      '[2 3 +] unquote

    [5]

    -Billy

## phimvt@lurac.latrobe.edu.au — 2003-07-04 07:05:59

    On Thu, 3 Jul 2003, Tanksley, William D. Jr. wrote:

    [..]

    > At the most primitive level, I purpose to remove Joy's current concept of

    > "quotations" by redefining all words which currently take a quotation into

    > words which take a function on the stack.

    You can at least get the appearance of this in Joy by suitable

    definitions:

        DEFINE   squareq  ==  [dup *] .

        [1 2 3 4]  squareq  map.         ==>   [1 4 9 16]

    [..]

    > The reasons I want to do this are many -- Joy's quotations have irritated me

    > on a theoretical level for a long time --

    I had noticed your dislike before, and it worried me. But I don't

    think I ever replied. Let me explain:

    Some languages treat functions as first class objects: functions can

    take functions as parameters and functions can return functions.

    Many more languages at least allow functions to take functions as

    parameters. Since these languages are lambda calculus based, any

    function used as a parameter must essentially be a lambda abstraction.

    It may of course be that the actual parameter is a word that has

    been to be a lambda abstraction, with perhaps syntactic sugar:

        DEFINITION    foo(x y)  =   ..x..y..           sugared

        DEFINITION    foo  =  Lambda x y : ..x..y..    raw

    The two are entirely equivalent.

    Now suppose we have a function that takes a function as one parameter,

    say the function bar. It may now use an explicit lambda abstraction

    or what has been defined to be a lambda abstraction:

            bar(Lambda x y : ..x..y.., other-parameters)

            bar(foo, other parameters)

    The two are entirely equivalent. The second looks neater, but it

    requires the definition of foo somewhere. If the function foo

    is only ever used once, as a parameter to the function bar, one

    might well prefer the explicit lambda and never define foo at all.

    If a language is not based on the lambda calculus but still

    will provide functions as parameters, then something else will

    have to take the place of lambda abstractions. Whatever that

    something is, it will have to be something that could be the

    body of a named function. It will have to be like  ..x..y..

    above, but do without the x and y. So let us write it as

    ..?..?.. . The details will depend on the details of the language.

    Semantically it might be a stack based language or one based

    on some other structure that serves a similar purpose.

    Syntactically it may be that ..?..?.. is actually a term

    f(g?,h?) with no need for an indicator where it starts and ends.

    But in a concatenative language there are no such terms,

    and some begin/end indicators are needed, Joy uses [ and ].

    So it seems to me that if Joy wants functions as parameters

    (indeed, functions as first class values), then it needs

    quotations. It so happens that they also allow other useful

    combinators such as dip, without the need for an explicit

    dip-stack (similar to the use of the return stack in Forth).

    Does one need functions as parameters to other functions?

    The functional programming community thinks that at least

    map, fold and filter are very useful for manipulating lists.

    Joy agrees. One does not need these higher order functions,

    of course, one can always write a recursive list precessing

    definition instead, using the standard patterns embodied

    in map, fold and filter. But that can become cumbersome

    if the function has to be defined even if it is used only once.

    Joy can even have combinators like linrec and binrec which

    have nothing in particular to do with lists. I think the

    same would be true for some other possible languages that

    are not based on the lambda calculus.

    Before embarking on this note, I should have asked you, Billy,

    whether your dislike is for the syntax of Joy quotations

    or for the semantics, or perhaps their use in higher order

    functions. I would be happy to elaborate.

    I am almost at the point where I should raise my question

    about adverbs in APL, J, K and cK, but right now I am too tired.

    Have a nice weekend.

      - Manfred

## Martin Young — 2003-07-04 11:28:35

    Curiously, or maybe not, Monkey already does something superficially

    quite similar to this but for different reasons: I wanted to add a

    simple type system to Monkey, and I wanted to be able to give a compiler

    static hints about which lists to compile.

    Each thing (for want of a better word) in a program has a major type and

    a minor type.  Major types are integers, floats, booleans, words, atoms,

    lists, etc.  Lists, for example, have two minor types: data and program.

    Most list manipulation words like cons, length, etc are defined for all

    things of major type list whereas words which take programs as

    parameters are defined only for things of major type list and minor type

    program.  List/program literals are denoted with curly braces whereas

    list/data literals use normal square brackets.

    Instead of "enclose" I have a word "programise" which turns a list/data

    into a list/program.  Similarly to Billy's description, I don't have a

    "disclose" equivalent and "programise" (or "enclose") is idempotent.

    Thus trying to execute "2 [ 2 + ] i" would cause a type error.  It would

    need to be either "2 [ 2 + ] programise i" or (preferably) "2 { 2 + }

    i".

    Where Monkey differs again is in a distinction between program words and

    atoms.  In Monkey, Manfred's example [peter paul mary] would cause an

    undefined word error on startup - every literal word must be either a

    primitive word or be defined in a module.  One would use atoms instead

    i.e. ['peter 'paul 'mary].  Atoms and words are separate major types -

    there is no general way to transform one into the other.

    I'm thinking that Billy's scalar execute word (let's call it si) is

    actually the atom->word transformer which I've disallowed.  That is, all

    words are, by default, not executed (in Monkey, they're of type atom not

    type word) but may be executed explicitly through a scalar execution

    word (in Monkey the datum of type atom would be transformed into a datum

    of type word then put in a unit list, programised and dequoted i.e. si

    == {{ atomtoword unit programise i }}.

    Now, I /think/ the distinction between words and atoms is syntactic

    sugar only.  One could simply use words instead and provide empty

    definitions for those ex-atoms which aren't useful words in their own

    right.  That is, my description of how si might be defined in Monkey is

    equally valid for Joy.

    If true then it's quite simple to synthesise Billy's described semantics

    in Joy.  That is, they don't actually add anything new, they're just

    another (albeit interesting) recasting of Joy in terms of different

    primitives.

    Am I missing something?  I don't, to be honest, see the problem

    (practically or theoretically) the recasting is intended to solve.

     On Thu, 2003-07-03 at 19:29, Tanksley, William D. Jr. wrote:

    > From: stevan apter [mailto:sa@...]

    > >ok, let's see if this matches what you're thinking.

    [snip]

    > I think you've got the basic idea, although all your examples are things I

    > won't be implementing (because I don't want to bother with enclose for now,

    > and I don't think disclose is worth the effort). Some other examples:

    [snip]

    --

    Martin Young, at home.

## Nick Forde — 2003-07-04 12:55:52

    Martin Young writes:

     [lots of interesting Monkey details...]

      > Now, I /think/ the distinction between words and atoms is syntactic

     > sugar only.  One could simply use words instead and provide empty

     > definitions for those ex-atoms which aren't useful words in their own

     > right.  That is, my description of how si might be defined in Monkey is

     > equally valid for Joy.

     >

     > If true then it's quite simple to synthesise Billy's described semantics

     > in Joy.  That is, they don't actually add anything new, they're just

     > another (albeit interesting) recasting of Joy in terms of different

     > primitives.

     >

     > Am I missing something?  I don't, to be honest, see the problem

     > (practically or theoretically) the recasting is intended to solve.

     After reading Billy's mail last night I reached the same conclusion

    but also thought I must be missing something. Even after sleeping on

    it I can see that explicitly distinguishing words and quotations may

    provide a compiler with some useful hints but I haven't yet found a

    compelling example to illustrate why one approach may be preferable to

    the other.

    John's example below did raise one question in my mind:

      "p" "op" concat intern [] cons i.

    In Joy is there any reason why 'i' may only work on quotations? Why

    not allow:

      1 2 "p" "op" concat intern i.

    1

    or:

      1 2 [pop] first i.

    1

    or even:

      1 2 i.

    2

    i.e. make the i combinator polymorphic so that it the following would

    be equivalent:

      1 2 [+ 2 *] i.

    6

      1 2 [+ 2 *] [null] [pop] [uncons [i] dip] tailrec.

    6

    Regards,

    Nick.

## stevan apter — 2003-07-04 13:59:42

    ----- Original Message -----

    From: "Nick Forde" <nickf@...>

    To: <concatenative@yahoogroups.com>

    Sent: Friday, July 04, 2003 8:55 AM

    Subject: RE: [stack] YACL - Yet Another Concatenative Language

    > Martin Young writes:

    >  [lots of interesting Monkey details...]

    >  > Now, I /think/ the distinction between words and atoms is syntactic

    >  > sugar only.  One could simply use words instead and provide empty

    >  > definitions for those ex-atoms which aren't useful words in their own

    >  > right.  That is, my description of how si might be defined in Monkey is

    >  > equally valid for Joy.

    >  >

    >  > If true then it's quite simple to synthesise Billy's described semantics

    >  > in Joy.  That is, they don't actually add anything new, they're just

    >  > another (albeit interesting) recasting of Joy in terms of different

    >  > primitives.

    >  >

    >  > Am I missing something?  I don't, to be honest, see the problem

    >  > (practically or theoretically) the recasting is intended to solve.

    >

    > After reading Billy's mail last night I reached the same conclusion

    > but also thought I must be missing something. Even after sleeping on

    > it I can see that explicitly distinguishing words and quotations may

    > provide a compiler with some useful hints but I haven't yet found a

    > compelling example to illustrate why one approach may be preferable to

    > the other.

      commute == [first unit [swap] match]

                 [1 swap drop            ]

                 [[swap] swap concat     ] ifte

       [+] commute

     [swap +]

       commute

     [+]

    if programs were atoms, you would need some way of breaking out the

    underlying list, prepending or removing the 'swap', then making

    the resulting list a program.  martin's 'programise' will do that,

    and so would enclose/disclose.  but i'm with you on the general question:

    what does this extra machinery buy you?  or perhaps:  what difficulties

    in the present approach does it extricate you from?

    >

    > John's example below did raise one question in my mind:

    >

    >   "p" "op" concat intern [] cons i.

    >

    > In Joy is there any reason why 'i' may only work on quotations? Why

    > not allow:

    >

    >   1 2 "p" "op" concat intern i.

    > 1

    >

    > or:

    >

    >   1 2 [pop] first i.

    > 1

    >

    > or even:

    >

    >   1 2 i.

    > 2

    >

    > i.e. make the i combinator polymorphic so that it the following would

    > be equivalent:

    >

    >   1 2 [+ 2 *] i.

    > 6

    >

    >   1 2 [+ 2 *] [null] [pop] [uncons [i] dip] tailrec.

    > 6

    right.  that's the way things work in cK.

        2 3 [+] first i

      5

    for any atom, disquotation of it is that atom:

        3 5 i

      3 5

    (this contradicts your example above:  why should 1 2 i -> 1?)

    >

    > Regards,

    >

    > Nick.

    >

    >

    >

    > To unsubscribe from this group, send an email to:

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

    >

    >

## stevan apter — 2003-07-04 14:03:21

    ----- Original Message -----

    From: "Martin Young" <martin@...>

    To: <concatenative@yahoogroups.com>

    Sent: Friday, July 04, 2003 7:28 AM

    Subject: RE: [stack] YACL - Yet Another Concatenative Language

    >

    > Now, I /think/ the distinction between words and atoms is syntactic

    > sugar only.  One could simply use words instead and provide empty

    > definitions for those ex-atoms which aren't useful words in their own

    > right.

    i think you're right.

    in implementing cK i struggled with this for a while and eventually

    decided to defer evaluation of words to run-time.  so e.g.

      [peter paul mary] `folksingers def

    `folksingers

      pop folksingers

    N N N

    def takes an object and a symbol, returns the symbol and has the

    side-effect of assigning the object to the symbol.  in this case,

    none of the words in folksingers is defined, so its value is a

    list three nulls.  but then if you say

      12 `peter def pop

      folksingers

    12 N N

    exit to k and look at folksingers:

      \

      folksingers

    ({o[x;get x;y]}[`peter];{o[x;get x;y]}[`paul];{o[x;get x;y]}[`mary])

    which is a list of three functions, each of which gets the value of

    the associated symbol.

    this is useful in defining mutually recursive functions:

        [ ... f ... ] `g def

        [ ... g ... ] `f def

## Nick Forde — 2003-07-04 14:31:25

    stevan apter writes:

      > > i.e. make the i combinator polymorphic so that it the following would

     > > be equivalent:

     > >

     > >   1 2 [+ 2 *] i.

     > > 6

     > >

     > >   1 2 [+ 2 *] [null] [pop] [uncons [i] dip] tailrec.

     > > 6

     >

     > right.  that's the way things work in cK.

     >

     >     2 3 [+] first i

     >   5

     >

     > for any atom, disquotation of it is that atom:

     >

     >     3 5 i

     >   3 5

     >

     > (this contradicts your example above:  why should 1 2 i -> 1?)

     Sorry, my examples only included the top-of-stack in results. My

    intention was also that for atoms, dequotation would be that atom.

    Here's an example definition of this polymorphic i combinator which

    works in the current Joy interpreter:

    DEFINE new_i  ==

      [

        [ [list]    i                ]

        [ [string]  intern [] cons i ]

        [ [user]    [] cons i        ]

        [ [set ]                     ]

        [ [char]                     ]

        [ [logical]                  ]

        [ [file]                     ]

        [ [integer]                  ]

        [ [] cons i                  ]

      ] cond.

    (Nb. There really should be a 'prim' test. If there had been I

    would have used the default condition for atoms).

    Some examples:

      [1 2 + 2 *] new_i.

    6

      1 2 "+" new_i.

    3

      1 2 "+" [new_i] first new_i.

    3

      {5} new_i.

    {5}

      'a new_i.

    'a

      true new_i.

    true

      stdin new_i.

    file:stdin

      1.01 new_i.

    1.01

      [cons] first 'a "b" rolldown new_i.

    "ab"

    And the ones from my earlier mail:

      1 2 [+ 2 *] new_i.

    6

      1 2 [+ 2 *] [null] [pop] [uncons [new_i] dip] tailrec.

    6

    I treated strings differently from other atoms to allow creation of

    mini interpreters. File streams could also be read and executed line

    by line.

    Regards,

    Nick.

## stevan apter — 2003-07-04 15:11:30

    ----- Original Message -----

    From: "Nick Forde" <nickf@...>

    To: <concatenative@yahoogroups.com>

    Sent: Friday, July 04, 2003 10:31 AM

    Subject: Re: [stack] YACL - Yet Another Concatenative Language

    [:]

    >

    > Here's an example definition of this polymorphic i combinator which

    > works in the current Joy interpreter:

    >

    > DEFINE new_i  ==

    >   [

    >     [ [list]    i                ]

    >     [ [string]  intern [] cons i ]

    >     [ [user]    [] cons i        ]

    >     [ [set ]                     ]

    >     [ [char]                     ]

    >     [ [logical]                  ]

    >     [ [file]                     ]

    >     [ [integer]                  ]

    >     [ [] cons i                  ]

    >   ] cond.

    :

    >   1 2 "+" new_i.

    > 3

    :

    > I treated strings differently from other atoms to allow creation of

    > mini interpreters. File streams could also be read and executed line

    > by line.

    should i expect that '"2 3 +" new_i' falls over?  i.e. that intern

    is not defined for such cases?

    APL has always had an 'execute', which takes a string and invokes

    the interpreter, and i have followed suit in cK:

        "2 3 +" ck

      5

        "[2 3 +]" ck

      [2 3 +]

    "ck" because i want to also have an exit to the k interpreter:

        "!3" k

      [0 1 2]

    >

    > Regards,

    >

    > Nick.

    >

    >

    >

    > To unsubscribe from this group, send an email to:

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

    >

    >

## Nick Forde — 2003-07-04 15:34:21

    stevan apter writes:

      >

     > >   1 2 "+" new_i.

     > > 3

     > :

     >

     > > I treated strings differently from other atoms to allow creation of

     > > mini interpreters. File streams could also be read and executed line

     > > by line.

     >

     > should i expect that '"2 3 +" new_i' falls over?  i.e. that intern

     > is not defined for such cases?

     Yes, new_i was meant for illustration only. I started writing a simple

    tokeniser but then realised that to be useful a full Joy parser would

    be required to distinguish atoms from words. Although this would be

    pretty easy to implement I decided that if this was a desirable

    feature then it should use the C Joy analyser and work with strings or

    file streams.

      > APL has always had an 'execute', which takes a string and invokes

     > the interpreter, and i have followed suit in cK:

     >

     >     "2 3 +" ck

     >   5

     >     "[2 3 +]" ck

     >   [2 3 +]

     I think this would be useful in Joy. A more flexible alternative may

    be to provide a 'tokenize' primitive that converts a string into a

    quotation. This wouldn't work so well with file streams though.

    Nick.

## John Cowan — 2003-07-04 20:11:19

    phimvt@... scripsit:

     > Before embarking on this note, I should have asked you, Billy,

    > whether your dislike is for the syntax of Joy quotations

    > or for the semantics, or perhaps their use in higher order

    > functions. I would be happy to elaborate.

     I think that would he doesn't like is the formal identity of lists and

    quotations, which prevents the compiling of quotations.

    In older Lisps, functions were lists, but in newer Lisps (especialy

    Scheme), functions are distinct objects created from lists.

    Indeed, one could create a dialect of Scheme in which lists/pairs/conses

    did not exist, and it would still be Scheme, provided a different

    mechanism was created for the representation of functions with

    arbitrarily many arguments (R5RS Scheme currently provides the arguments

    in the form of a freshly created list).

    --

    Schlingt dreifach einen Kreis vom dies!    John Cowan <jcowan@...>

    Schliesst euer Aug vor heiliger Schau,     http://www.reutershealth.com

    Denn er genoss vom Honig-Tau,              http://www.ccil.org/~cowan

    Und trank die Milch vom Paradies.            -- Coleridge (tr. Politzer)

## stevan apter — 2003-07-04 21:28:03

    i think i have an argument for a distinct category of function

    objects, but it's regrettably convoluted, and i don't know if

    anyone will find it convincing.

    in k, the shape of an array is defined this way:

    the shape of an atom is the empty list.

    the shape of a list x is the size of x to which is append the

    common initial sublist of the shapes of its elements.

    so shape is always a list of integers (possibly empty).

    the idea is that you want to penetrate a list as far as

    possible, up to the point where you can no longer summarize

    the sizes of the lists at that level in a single integer.

    examples:

        10 shape

      []

        [1 2 3] shape

      [3]

        [[1 2 3][4 5 6]] shape

      [2 3]

        [[1 2 3][4 5]] shape

      [2]

    functions are atoms, so they have empty shape.  the size of

    the shape is called 'rank'.  atoms are rank 0, vectors are

    rank 1, matrices are rank 2, &c.  notice that [[1 2 3][4 5]]

    is rank 1, even though its elements are lists.

    the rank of an object is related to how it can be indexed.

    a vector can be indexed v[i], a matrix m[i;j], and so forth.

    atoms can't be indexed.  the shape of the result of an index

    can be calculated by replacing each element in the shape

    with the shape of the corresponding index.  for example, if

    m has shape [3 4] then the shape of m[1 2;0 2 1] is [2 3],

    and that of m[1;0 1] is [2] (since 1 is an atom, we replace

    the corresponding element of the shape -- 3 -- with [].)

    there is a related concept for functions -- valence.  the

    valence of a function is the number of arguments it takes.

    e.g. the valence of + is 2, that of {x+y-z} 3, and so forth.

    since functions are atoms, and atoms can't be indexed, we

    re-use the brackets to mean function application:  +[2;3],

    {x+y-z}[4;5;6], &c.

    now we can define the shape of a function of valence k to be

    [-1 .. -k].  so the shape of + is [-1 -2], that of {x+y-z}

    [-1 -2 -3] &c.

    so e.g. the shape of p = [+ -] is 2 -1 -2.

    now consider the transpose operation, which flips the first

    two axes of an array of rank > 1.  if [a b ..] is the shape

    of x, then the shape of transposed x is [b a ..].  so the

    shape of [+ -] transposed is [-1 2 -2].  what is that thing?

    if we believe what the shape is telling us, then it's a

    function of two arguments which returns something of shape

    [2 ..].  in fact, it's a function which returns a list whose

    first element is x+y and whose second is x-y.  the transpose

    of a list of functions (of the same shape) is a function.

    not only primitives, but also constructed programs have

    valence, so they too should have shape in this extended sense.

    but if programs are lists, then we can't extend shape or transpose

    or any other structural operation in this way.  the reason we

    can't is that [+ *] has shape [2 -1 -2] (it's a list of two

    function atoms!), whereas we want it to have shape [-1 -2 -3].

    that is, we want to be able to form the list [+ -] with shape

    [2 -1 -2], but we also want to be able to construct the program

    of shape [-1 -2 -3] which in joy we also write [+ -].

     ----- Original Message -----

    From: "John Cowan" <cowan@...>

    To: <concatenative@yahoogroups.com>

    Sent: Friday, July 04, 2003 4:11 PM

    Subject: Re: [stack] YACL - Yet Another Concatenative Language

    > phimvt@... scripsit:

    >

    > > Before embarking on this note, I should have asked you, Billy,

    > > whether your dislike is for the syntax of Joy quotations

    > > or for the semantics, or perhaps their use in higher order

    > > functions. I would be happy to elaborate.

    >

    > I think that would he doesn't like is the formal identity of lists and

    > quotations, which prevents the compiling of quotations.

    >

    > In older Lisps, functions were lists, but in newer Lisps (especialy

    > Scheme), functions are distinct objects created from lists.

    > Indeed, one could create a dialect of Scheme in which lists/pairs/conses

    > did not exist, and it would still be Scheme, provided a different

    > mechanism was created for the representation of functions with

    > arbitrarily many arguments (R5RS Scheme currently provides the arguments

    > in the form of a freshly created list).

    >

    > --

    > Schlingt dreifach einen Kreis vom dies!    John Cowan <jcowan@...>

    > Schliesst euer Aug vor heiliger Schau,     http://www.reutershealth.com

    > Denn er genoss vom Honig-Tau,              http://www.ccil.org/~cowan

    > Und trank die Milch vom Paradies.            -- Coleridge (tr. Politzer)

    >

    >

    > To unsubscribe from this group, send an email to:

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

    >

    >

## Tanksley, William D. Jr. — 2003-07-07 14:59:26

    From: stevan apter [mailto:sa@...]

     >that is, we want to be able to form the list [+ -] with shape

    >[2 -1 -2], but we also want to be able to construct the program

    >of shape [-1 -2 -3] which in joy we also write [+ -].

     Wow. You've stated my problem formally and precisely: I want to be able to

    distinguish between programs and lists of programs.

    The idea of giving functions negative rank is new to me.

    -Billy

## Tanksley, William D. Jr. — 2003-07-07 18:39:42

    From: phimvt@... [mailto:phimvt@...]

     >On Thu, 3 Jul 2003, Tanksley, William D. Jr. wrote:

    >>At the most primitive level, I purpose to remove Joy's

    >>current concept of "quotations" by redefining all words

    >>which currently take a quotation into words which take

    >>a function on the stack.

    >You can at least get the appearance of this in Joy by suitable

    >definitions:

    >    DEFINE   squareq  ==  [dup *] .

    >    [1 2 3 4]  squareq  map.         ==>   [1 4 9 16]

     You can get the reality of this in Joy by suitable definitions:

    DEFINE execute == enlist i.

     2 3 [+] first execute.    ==> 5

    Of course, I don't have the ability to use function references directly, but

    as you can see I can just use [?] first as a substitute.

    I could define all of the combinators for my system using Joy's combinators,

    and if I were attempting to produce a successor to Joy, I would do this as a

    proof of concept.

     >>The reasons I want to do this are many -- Joy's quotations

    >>have irritated me on a theoretical level for a long time --

    >I had noticed your dislike before, and it worried me. But I don't

    >think I ever replied. Let me explain:

     I've never before been able to articulate my dislike properly, and naturally

    nobody's understood it. Apter has done me the favor of expressing

    _precisely_ my problem with quotations, although in very technical terms; a

    less formal way of stating my problem is that I want to be able to treat

    lists differently from functions.

     >If the function foo is only ever used once, as a parameter to

    >the function bar, one might well prefer the explicit lambda

    >and never define foo at all.

     One _might_ prefer that -- or one might not. Or the language might not offer

    the option. Python, although it offers lambdas, deliberately cripples them

    (even in the current version of the language, which has lexical scoping at

    last); programmers traditionally define a function named "_" and pass that,

    if they can't think of a more meaningful name.

    Let me invent a couple of terms. A "function literal" is how you pass any

    function as a parameter (or return value). Lisp uses #' to express function

    literals. An "expression literal" allows you to treat an expression as a

    literal, in order to pass it or manipulate it.

    To support first-class functions you have to support function literals. You

    DON'T have to support expression literals.

    Joy has expression literals (quotations), but it uses them *instead* of

    function literals. Function literals don't appear in Joy's syntax or

    definition, even though Joy programs can accept and return functions ([+]

    first returns a function).

     >So it seems to me that if Joy wants functions as parameters

    >(indeed, functions as first class values), then it needs

    >quotations. It so happens that they also allow other useful

    >combinators such as dip, without the need for an explicit

    >dip-stack (similar to the use of the return stack in Forth).

     Anything that quotations can do, functions can do as well.

    Almost anything.

    Quotations, as I've mentioned before, are expression literals; as such, you

    can do expression manipulation on them. You can't neccessarily do that for

    functions.

    Quotations do serve a useful purpose. My problem isn't really their

    presence, although my language won't initially have them; my problem is that

    people are confusing them with functions, and as a result having all kinds

    of theoretical confusion involving equality and such. This theoretical

    confusion leads to a slowdown of progress in understanding this new topic,

    concatenative languages; it also limits the functionality we could be

    adding, for example combinators that handle arbitrary lists of functions and

    items (which doesn't work if you can't tell the difference between a list

    and a function).

     >I am almost at the point where I should raise my question

    >about adverbs in APL, J, K and cK, but right now I am too tired.

     cK demonstrates that K's adverbs are most similar to combinators.

    J is a little more complex, but the same essentials apply.

     >  - Manfred

     -Billy

## sa@dfa.com — 2003-07-07 18:41:18

    From: stevan apter [mailto:sa@...]

     >that is, we want to be able to form the list [+ -] with shape

    >[2 -1 -2], but we also want to be able to construct the program

    >of shape [-1 -2 -3] which in joy we also write [+ -].

     Wow. You've stated my problem formally and precisely: I want to be able to

    distinguish between programs and lists of programs.

         + is a function atom, [+ -] is a list of functions,

         [+ -] transpose is a function-list (or "function-

         array" - btw [-] tranpose commutes -).

    The idea of giving functions negative rank is new to me.

         i think it works, but n.b. the valence of {2 3 +}

         (or however you choose to write it) is 0, so the

         shape is [].  that throws a wrench into what i

         was thinking at first:  x is a function if x shape

         first 0 <.

    -Billy

    To unsubscribe from this group, send an email to:

    concatenative-unsubscribe@egroups.com

    Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

## Tanksley, William D. Jr. — 2003-07-07 18:49:50

    From: sa@... [mailto:sa@...]

     >[Billy said:]

    >>The idea of giving functions negative rank is new to me.

    >i think it works, but n.b. the valence of {2 3 +}

    >(or however you choose to write it) is 0, so the

    >shape is [].  that throws a wrench into what i

    >was thinking at first:  x is a function if x shape

    >first 0 <.

     Hm. Yes, I see other problems too -- for example, what's the shape of {3 2}?

    How about {3 + 3}?

    Shape doesn't seem unreasonable to me; in fact, it's the basis for my plans

    for my language. But functions don't have a shape the same way literal

    arrays have a shape; instead, they have a stack effect, and each item in the

    effect has a shape. Literals also have a shape.

    -Billy

## sa@dfa.com — 2003-07-07 19:38:43

    [billy said:]

    Hm. Yes, I see other problems too -- for example, what's the shape of {3

    2}?

    How about {3 + 3}?

         and then there's [[*] times] and [[0 <] [*] [+ *] ifte] and ...

         my argument was that if you want function arrays, then they can't

         be lists.  it may be that function arrays aren't important, or

         useful, or that they introduce too many complexities.  i just

         don't know.

## Tanksley, William D. Jr. — 2003-07-07 21:01:23

    From: Martin Young [mailto:martin@...]

     >Where Monkey differs again is in a distinction between program

    >words and

    >atoms.  In Monkey, Manfred's example [peter paul mary] would cause an

    >undefined word error on startup - every literal word must be either a

    >primitive word or be defined in a module.  One would use atoms instead

    >i.e. ['peter 'paul 'mary].  Atoms and words are separate major types -

    >there is no general way to transform one into the other.

     I would have a general way to trasfer between the two. Oh, and I wouldn't

    call them "atoms"; by my terms they're "symbols". Anyhow, to convert from a

    symbol to a function one uses 'lookup', and to convert from a function to a

    symbol one uses 'name'.

     >I'm thinking that Billy's scalar execute word (let's call it si) is

    >actually the atom->word transformer which I've disallowed.

     No, not at all. Scalar execute simply executes the function on TOS. In your

    terms, it takes a word as input.

     >That is, all words are, by default, not executed (in Monkey, they're of

    >type atom not type word)

     No. As with Joy, words are executed (or compiled) by default. The way to

    place a function on the stack is to quote its name. One possible syntax is a

    preceding apostrophe, as with Lisp and Forth.

     >Now, I /think/ the distinction between words and atoms is syntactic

    >sugar only.

     No -- symbols are used in many modern languages. It's very useful to be able

    to express arbitrary symbols.

    Assuming, of course, that by "words" you mean "functions" and by "atoms" you

    mean "symbols".

     >Am I missing something?  I don't, to be honest, see the problem

    >(practically or theoretically) the recasting is intended to solve.

     You've already implemented the major difference: Monkey can tell the

    difference between a function and a list of data. The next step is to take

    advantage of that: I will do so by implementing combinators which traverse

    lists executing functions wherever they appear. This is something that's not

    possible in Joy as it stands.

    -Billy (for greater justice)

## Tanksley, William D. Jr. — 2003-07-07 21:07:59

    From: stevan apter [mailto:sa@...]

     >  commute == [first unit [swap] match]

    >             [1 swap drop            ]

    >             [[swap] swap concat     ] ifte

    >   [+] commute

    > [swap +]

    >   commute

    > [+]

    >if programs were atoms, you would need some way of breaking out the

    >underlying list, prepending or removing the 'swap', then making

    >the resulting list a program.  martin's 'programise' will do that,

    >and so would enclose/disclose.

     This is something Joy already can do. My Forth/Joy won't be able to do it at

    all: it won't have any way to decompile or disclose to convert a function

    into a list. I will probably eventually write a word which will convert a

    list into a function, but I won't initially.

    Why not? Simply because I don't need constructed functions right now.

    They're a specialised need that I don't have. Once I build a global

    optimiser, of course, I _will_ need them; but it's not certain to me that

    I'll need a global optimiser. Simple native-code generation with basic

    peephole optmization and register allocation tends to get very close to GCC

    performance for Forth, and I don't see why my language should be any

    different.

    -Billy

## phimvt@lurac.latrobe.edu.au — 2003-07-08 06:18:17

    On Fri, 4 Jul 2003, John Cowan wrote:

     > phimvt@... scripsit:

    >

    > > Before embarking on this note, I should have asked you, Billy,

    > > whether your dislike is for the syntax of Joy quotations

    > > or for the semantics, or perhaps their use in higher order

    > > functions. I would be happy to elaborate.

    >

    > I think that would he doesn't like is the formal identity of lists and

    > quotations, which prevents the compiling of quotations.

                         ????????

    I don't see that at all. I have spent very little time thinking

    about how a compiler for Joy would work, but if it can compile

    the body of a definition (which is a term), then it can compile

    a quotation (which is also a term), except that it might have to

    invent an internal name for that compiled form. Assuming that the

    Joy compiler produces C code, then e.g.

        [..if-part..]  [..then-part..]  [..else-part..]  ifte

    becomes three functions, say  f42(), f43(), f44(), and for the

    ifte the code

        f42();

        if (TOS > 1) f(43);

        else f44();

    The C optimiser can then decide whether the calls to f42(), f43()

    and f44() should be inlined. Alternatively the Joy compiler can

    do the inlining.

    In most Joy programs the quotation parameters immediately precede

    the combinators, and the above method should work. In general it

    would not be necessary to _also_ retain the quotation in source form.

    This is so because all inbuilt combinators and also all library

    combinators are _extensional_, in this sense:

        for all programs P and Q and for all combinators C,

        IF   P  ==  Q   THEN   [P] C  ==  [Q] C

    Certainly it is possible to write _intensional_ combinators

    for which this is not true, e.g. an intensional i combinator i-i :

        DEFINE  i-i  ==  dup put i.

    Or an intensional map:

        DEFINE  i-map  ==  dup [map] dip swons.

        [1 2 3]  [2 *]      map         ==>   [2 4 6]

        [1 2 3]  [dup +]    map         ==>   [2 4 6]

        [1 2 3]  [2 *]    i-map         ==>   [[2 *] 2 4 6]

        [1 2 3]  [dup +]  i-map         ==>   [[dup +] 2 4 6]

    I have never seen the need to define intensional combinators,

    but maybe one day it will happen. In that case a compiler

    will have to produce _both_ the quoted program and the

    compiled form of the quotation. But in most cases the compiler

    should be able to work out what is needed. Moreover, in the

    simplest implementation the compiler could always do both: retain

    the source text and produce the compiled form of a quotation.

    It is interesting to note that good compilers already do

    this to some extent with runtime error checking: depending

    on the debug switches, at least the line number or also

    the name of the offending operator or even the whole line

    is retained to become available for error reporting.

    So, if a first version of a Joy compiler did that for every

    quotation, it would not be an enormous disaster.

    These are my somewhat ill-formed thoughts. Am I missing something?

    I will be busy preparing for my courses that are starting soon,

    so I will have little time to contribute to the mailing group.

    In the meantime my best wishes to the (four ?) people who are

    implementing various cousins of Joy.

      - Manfred

## phimvt@lurac.latrobe.edu.au — 2003-07-08 06:42:45

    On Fri, 4 Jul 2003, Nick Forde wrote:

    [..]

    > Here's an example definition of this polymorphic i combinator which

    > works in the current Joy interpreter:

    >

    > DEFINE new_i  ==

    >   [

    >     [ [list]    i                ]

    >     [ [string]  intern [] cons i ]

    >     [ [user]    [] cons i        ]

    >     [ [set ]                     ]

    >     [ [char]                     ]

    or:   [ [char]  "" cons intern [] cons i ]

      ( to allow for  'i  and 'x and 'y      to be consistently polymorphic

    >     [ [logical]                  ]

    >     [ [file]                     ]

    >     [ [integer]                  ]

    or:   [ [integer] chr "" cons intern [] cons i ]

      ( to allow for  105 and 120 and 121 ('i, 'x, 'y)  to be consistent

    >     [ [] cons i                  ]

    >   ] cond.

    >

    > (Nb. There really should be a 'prim' test. If there had been I

    > would have used the default condition for atoms).

      (NB. Yes, maybe a prim test, I agree.)

    But then the same should be done for all combinators C. Moreover,

    it should be done for all operators O too. In that case what little

    typechecking there is in Joy would completely go out of the window,

    and it would make programming more error prone.

    In the rare case where one really wants the latitude which your

    new-i and all other new-C and new-O offer, one is probably equally

    well served with a 'quotify' operator  -  defined pretty much like

    your new-i but without the terminal i at the end of each case.

      - Manfred

## John Cowan — 2003-07-08 11:16:53

    phimvt@... scripsit:

     >     [..if-part..]  [..then-part..]  [..else-part..]  ifte

    > becomes three functions, say  f42(), f43(), f44(), and for the

    > ifte the code

    >     f42();

    >     if (TOS > 1) f(43);

    >     else f44();

    > The C optimiser can then decide whether the calls to f42(), f43()

    > and f44() should be inlined. Alternatively the Joy compiler can

    > do the inlining.

     Sure.  There's no problem with handling lots of individual cases like

    this.  It's the general case that's hard:

    	32 [] cons 45 swons 56 swons i

    where you have to do an arbitrary amount of analysis, perhaps involving

    actual (not abstract) interpretation, to even figure out what the

    program is.  In Scheme, by contrast, the difference between a function

    and a mere list is always lexically visible: the body of a function

    cannot (short of using "eval") be concocted at run time in this fashion.

    It is in this sense I say that a Joy program *is* a list, as was the

    case in early Lisps, whereas in modern Lisps, functions are *made from*

    lists.  At run-time, the two objects are quite distinguishable.

    --

    John Cowan  jcowan@...  www.ccil.org/~cowan  www.reutershealth.com

    "If I have seen farther than others, it is because I was standing on

    the shoulders of giants."

            --Isaac Newton