# implementations

## stevan apter — 2000-05-23 12:38:12

    where do we stand on implementations of joy?

    billy?  how's yours going?

    as you (billy) know, i threw together a quick and dirty version in k,

    sans sets, but other work (the paying kind) drew me away before i could

    disentangle the meanings of several of the more exotic recursive

    combinators (e.g. treegenrec).

    having spent a few days reading through manfred's papers, i'm still

    left wondering where the canonical enumeration of the joy primitives

    may be found, as the definition seems to vary across papers.

## iepos@tunes.org — 2000-05-23 14:11:14

    > where do we stand on implementations of joy?

     I'm still planning on working some more sometime on CLIP,

    my project for an efficient implementation of a Joy-like system.

    The current version is available at

      http://tunes.org/~iepos/clip/clip-joyful-0.5.tar.gz

    It is writting in C and operates by compiling to native x86 code at

    runtime (thus it will only work if you're using an x86 processor).

    However, right now, it is not very efficient, has at least one bug,

    is lacking many important primitives, and has no documentation.

     > having spent a few days reading through manfred's papers, i'm still

    > left wondering where the canonical enumeration of the joy primitives

    > may be found, as the definition seems to vary across papers.

     Perhaps what you're looking for is the "Joy manual", available on

    his site, or by typing "manual ." into the interpreter.

    - Brent Kerby ("iepos")

## stevan apter — 2000-05-24 00:38:04

    thanks - i've attached my work-in-progress version of joy in k (joy.k)

    to run the interpreter, download k from www.kx.com - the k interpreter

    is only 150k or so, and installs instantaneously.

    to run joy, from a command prompt say:

        k joy

    the joy prompt is:

        joy>

    to exit to the k console, an empty carriage return; to re-enter the

    joy interpreter, in the k console say:

        J[]

    (which happens to be the final line of joy.k)

    at the point where i left things, one could define and successfully

    evaluate such combinators as:

    unitlist:I"[]cons"

    shunt:I"[swons]step"

    reverselist1:I"[]swap shunt"

    reverselist2:I"[]swap infra"

    restlist:I"[null][unitlist][dup rest][cons]linrec"

    frontlist:I"[null][unitlist][uncons][[cons]map popd dup first rest swons]linrec"

    subseqlist1:I"frontlist[restlist]map"

    subseqlist2:I"[null][unitlist][uncons dup[frontlist[cons]map popd]dip][concat]linrec"

    powerlist1:I"[null] [[] cons] [uncons][dup swapd [cons] map popd concat] linrec"

    powerlist2:I"[null] [[] cons] [uncons][dup swapd [cons] map popd swoncat] linrec"

    treesum:I"0 swap[+]treestep"

    treesize:I"0 swap[pop succ]treestep"

    treeshunt:I"[swons]treestep"

    treeflatten:I"[]swap treeshunt reverse"

    the function I parses joy concatenations into k lists; e.g.

      frontlist

    (,`null

     ,`unitlist

     ,`uncons

     (,`cons

      `map

      `popd

      `dup

      `first

      `rest

      `swons)

     `linrec)

    a surprising (and gratifying) side-effect of implementing joy in a vector

    language is that the atomic primitives automatically extend to higher-dimensional

    lists:

        joy>[1 2 3][4 5 6]+

        [5 7 9]

        joy>[[1 2][3 4]][[5 6][7 8]]+

        [5 7 9] [[6 8] [10 12]]

    if i decide to continue with this project, i'll probably discard the existing

    code and think it through again.

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

    From: <iepos@...>

    To: <concatenative@egroups.com>

    Sent: Tuesday, May 23, 2000 10:11 AM

    Subject: Re: [stack] implementations

    > > where do we stand on implementations of joy?

    >

    > I'm still planning on working some more sometime on CLIP,

    > my project for an efficient implementation of a Joy-like system.

    > The current version is available at

    >

    >   http://tunes.org/~iepos/clip/clip-joyful-0.5.tar.gz

    >

    > It is writting in C and operates by compiling to native x86 code at

    > runtime (thus it will only work if you're using an x86 processor).

    > However, right now, it is not very efficient, has at least one bug,

    > is lacking many important primitives, and has no documentation.

    >

    > > having spent a few days reading through manfred's papers, i'm still

    > > left wondering where the canonical enumeration of the joy primitives

    > > may be found, as the definition seems to vary across papers.

    >

    > Perhaps what you're looking for is the "Joy manual", available on

    > his site, or by typing "manual ." into the interpreter.

    >

    > - Brent Kerby ("iepos")

    >

    > ------------------------------------------------------------------------

    > Failed tests, classes skipped, forgotten locker combinations.

    > Remember the good 'ol days

    > http://click.egroups.com/1/4053/6/_/_/_/959091164/

    > ------------------------------------------------------------------------

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

    [Non-text portions of this message have been removed]

## stevan apter — 2000-05-24 00:40:17

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

    From: stevan apter <apter@...>

    To: <concatenative@egroups.com>

    Sent: Tuesday, May 23, 2000 8:38 PM

    Subject: Re: [stack] implementations

    > thanks - i've attached my work-in-progress version of joy in k (joy.k)

    >

    i guess we're filtering attachments in this group.  fortunately, the code

    is small enough to list:

    / joy in k

    / joy <-> k (quick & dirty)

    \d Parse

    types:{:[4:x;type x;_f'x]}

    type:{:[(*x)_in*Ops;Ops[1;Ops[0]?*x];&/x _lin".0123456789";. x;"\""=*x;1_-1_ x;"'"=*x;x 1;`$x]}

    parts:{a:ol x;b:"["=*:'a;a[&b],:;a:@[a;&~b;ob];r:(,/a)_dv"";@[r;&"["=*:'r;_f 1_-1_]}

    sa:{,/@[x;&uq[x]&x=y;:[;" ",y," "]]}

    ol:{(&1(~=)':ls x)_ x}

    ob:{1_'(&uq[x]&x=" ")_ x:" ",x}

    uq:{~(0<':b)|b:(~=)\(~(!#x)_lin,/0 1+/:x _ss"\\\"")&x="\""}

    ls:{~|':~=/+\'uq[" ",x]&/:(" ",x)=/:"[]"}

    nl:{@[x;&x _lin"\n\t";:;" "]}

    vm:{:[4:x;x,"";1_,/" ",'x]}

    in:{types parts(nl vm x)sa/"[]",*Ops}

    out:{(1_,/(" ",term@)'|x),"\n"}

    term:{:[-3=t:4:x;"\"",x,"\"";1>t;list@_f'x;t=3;"'",x;t=5;_f(+($!x;x[]);`dict);$(Ops[0],,x)Ops[1]?x]}

    list:{"[",(1_,/" ",'$x),"]"}

    Ops:("&|~+-*/%=<>";`and`or`not`plus`minus`mul`idiv`div`eq`lt`gt)

    \d ^

    / eval, console, &c.

    E:{:[~4=4:y;(,y),x;7=4:v:. y;v x;6=4:v;(,$y),x;x _f/v]}

    X:()E/

    Y:()E\

    O:Parse.out

    I:Parse.in

    R:{`0:O r:x E/y;r}

    S:{`0:,/O'r:x E\y;*|r}

    J:{s:();o:(R;S);while[#r:{`0:"joy>";0:`}[];:["\\"=*r;o|:;s:(*o)[s;I r]]]}

    / utilities

    Two:{(,x),y;(,Dot[x;2#y]),2 _ y}

    One:{@[y;0;x]}

    Dot:{:[-3=4:y;.($x),"[",(1_,/";",'"\"",'y,'"\""),"]";x . y]}

    Num:{(_ci;::)[(b~z)&a~y]x[b:Ic z;a:Ic y]}

    Ic:{:[3=4:*x;_ic x;x]}

    Rel:{x[Ic z;Ic y]}

    Each:{y{*(,x)E/y}\:x}

    Ary:{((1_ y)E/*y),(x+1)_ y}

    App:{(((x#1_ y),\:(x+1)_ y)E/\:*y),(x+1)_ y}

    Dip:{(x#1_ y),((1+x)_ y)E/*y}

    Type:{:[4=4:x;x;~4:x;();-3=4:x;"";*0#x]}

    Leaf:{(&/@:'x)|(@x)|-3=4:x}

    / assignment

    is:Two[{.[`$x;();:;y]}]

    / general operators

    id:(::)

    false:{0,x}

    true:{1,x}

    stack:{(,x),x}

    newstack:{x;()}

    unstack:{x[0],1_ x}

    pop:1_

    dup:{x[,0],x}

    swap:{@[x;1 0;:;2#x]}

    rollup:{x[1 2 0],3_ x}

    rolldown:{x[2 0 1],3_ x}

    choice:{(x[0 1]x 3),3_ x}

    opcase:Two[{((1_'-1_ x),,*|x)((Type@*:)'-1_ x)?Type@*y}]

    swapd:I"[swap]dip"

    dupd:I"[dup]dip"

    popd:I"[pop]dip"

    popop:I"pop pop"

    / i/o

    put:{}

    get:{}

    load:{(1_ x)E/I@0:x[0],".joy"}

    / atomic operators

    max:or:Two[Num[|]]

    min:and:Two[Num[&]]

    not:One[~:]

    plus:Two[Num[+]]

    minus:Two[Num[-]]

    mul:Two[*]

    div:Two[{y%x}]

    rem:Two[{y!x}]

    flr:One[_:]

    idiv:I"div flr"

    sign:One[{(-x<0)+0<x}]

    abs:One[_abs]

    pred:One[Num[+;-1]]

    succ:One[Num[+;1]]

    / list operators

    cons:Two[{(,y),x}]

    swons:I"swap cons"

    first:One[*:]

    second:One[{x 1}]

    third:One[{x 2}]

    last:One[*|:]

    rest:One[1_]

    of:Two[{x:[1=4:y;y;`$y]}]

    at:I"swap of"

    drop:Two[_]

    take:Two[#]

    size:One[#:]

    reverse:One[|:]

    uncons:{((1_;*:)@\:*x),1_ x}

    unswons:I"uncons swap"

    flatten:One[,/]

    transpose:One[+:]

    concat:Two[{y,x}]

    swoncat:Two[,]

    transpose:One[+:]

    dict:One[{..[x;(;0);`$]}]

    / predicates

    null:One[{:[@x;x=0;~#x]}]

    small:One[{:[@x;x<2;2>#x]}]

    gt:Two[Rel[>]]

    lt:Two[Rel[<]]

    eq:Two[Rel[=]]

    le:Two[Rel[~>]]

    ge:Two[Rel[~<]]

    ne:Two[Rel[~=]]

    equal:Two[~]

    has:Two[_in]

    in:Two[{y _in x}]

    / general combinators

    i:{(1_ x)E/*x}

    x:{x E/*x}

    y:{}

    b:{((2_ x)E/x 1)E/*x}

    nullary:Ary[0]

    unary:Ary[1]

    binary:Ary[2]

    ternary:Ary[3]

    dip:Dip[1]

    dipd:Dip[2]

    dipdd:Dip[3]

    app1:App[1]

    app2:App[2]

    app3:App[3]

    app4:App[4]

    cleave:{((2_ x){*x E/y}/:2#x),3_ x}

    construct:{}

    ifte:{((3_ x)E/x@~~*(3_ x)E/x 2),4_ x}

    cond:{c:*x;s:1_ x;while[1<#c;if[*s E/*c;:s E/c 1];c:2_ c]}

    whiledo:{s:2_ x;while[*s:s E/x 1;s:s E/*x];s}

    primrec:{:[x 2;(x[2],_f[@[x;2;-;1]])E/*x;(3_ x)E/x 1]}

    linrec:{:[*(4_ x)E/x 3;(4_ x)E/x 2;(_f(4#x),(4_ x)E/x 1)E/*x]}

    tailrec:{:[*(3_ x)E/x 2;(3_ x)E/x 1;_f(3#x),(3_ x)E/*x]}

    binrec:{:[*(4_ x)E/x 3;(4_ x)E/x 2;((*_f@)'x{@[x;4;:;y]}/:2#(4_ x)E/x 1)E/*x]}  / ?

    genrec:{:[*(4_ x)E/x 3;(4_ x)E/x 2;(`genrec,(4#x),(4_ x)E/x 1)E/*x]}

    condlinrec:{}

    / atomic combinators

    branch:{((3_ x)E/x@~~z),4_ x}

    times:{x[0]{y E/x}[x 1]/2_ x}

    / list combinators

    infra:{(,x[1]E/*x),2_ x}

    step:{{((,z),y)E/x}[*x]/[2_ x;x 1]}

    map:{(,(1_'@[x;1;:;]'x 1){*x E/y}\:*x),2_ x}

    fold:{(,{*(z;y)E/x}[*x]/[x 1;x 2]),3_ x}

    filter:{1_@[x;1;@[;&*map x]]}

    split:{((x[1]@&:;x[1]@&~:)@\:*map x),2_ x}

    some:{@[map x;0;|/]}

    all:{@[map x;0;&/]}

    / tree combinators

    treestep:{:[Leaf x 1;step x;(,(*_f@)'x[1]{@[y;1;:;x]}\:x),2_ x]}

    treerec:{:[Leaf x 2;(2_ x)E/x 1;((,`treerec,2#x),(2_ x))E/*x]}

    treegenrec:{}

    unitlist:I"[]cons"

    shunt:I"[swons]step"

    reverselist1:I"[]swap shunt"

    reverselist2:I"[]swap infra"

    restlist:I"[null][unitlist][dup rest][cons]linrec"

    frontlist:I"[null][unitlist][uncons][[cons]map popd dup first rest swons]linrec"

    subseqlist1:I"frontlist[restlist]map"

    subseqlist2:I"[null][unitlist][uncons dup[frontlist[cons]map popd]dip][concat]linrec"

    powerlist1:I"[null] [[] cons] [uncons][dup swapd [cons] map popd concat] linrec"

    powerlist2:I"[null] [[] cons] [uncons][dup swapd [cons] map popd swoncat] linrec"

    treesum:I"0 swap[+]treestep"

    treesize:I"0 swap[pop succ]treestep"

    treeshunt:I"[swons]treestep"

    treeflatten:I"[]swap treeshunt reverse"

    qsort:I"[small] [] [uncons [>] split] [swapd dip cons concat] binrec"

    J[]

## wtanksley@bigfoot.com — 2000-05-25 19:30:33

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

     >where do we stand on implementations of joy?

    >billy?  how's yours going?

     I've been distracted by a couple of work deadlines and another hobby project

    (Omega, an old Roguelike whose maintainership I've taken up).  Fortunately,

    I found another project which will be able to "sponsor" my JoyForth (in the

    sense of acting interested in using my code, not in the sense of

    contributing any money or time).

    Aside from that, I'm still getting the feel of the language; I'm good with

    Forth, and I'm good at scoping out languages, but the idea that Forth and

    Joy and Postscript (and so on) form an entirely different classification of

    languages still is new to me.

    I've mentioned before that I intend to design two languages: one a Joy-like

    Forth, and another a Forth-like Joy.  The Joy-like Forth will have all of

    the simplicity, tiny size, and easy implementation of Forth while hopefully

    giving us some of the clarity of Joy; the Forth-like Joy will have the

    conceptual clarity and automation (including garbage collection and inline

    quotations) of Joy together with the proven practicality of Forth.

    So I have to learn first what makes Joy clear, and then what makes Forth

    practical.

    -Billy

## stevan apter — 2000-06-02 12:37:28

    >

    > > having spent a few days reading through manfred's papers, i'm still

    > > left wondering where the canonical enumeration of the joy primitives

    > > may be found, as the definition seems to vary across papers.

    >

    > Perhaps what you're looking for is the "Joy manual", available on

    > his site, or by typing "manual ." into the interpreter.

     hi brent

    i'm inclined to take the joy manual as the current standard

    definition of the language, but if you look at some of the

    other papers, you'll see that there are other, non-identical

    lists of primitives given.

    btw, have you answered your original question about 'dip'?

     >

    > - Brent Kerby ("iepos")

    >

## iepos@tunes.org — 2000-06-02 13:58:53

    > > > having spent a few days reading through manfred's papers, i'm still

    > > > left wondering where the canonical enumeration of the joy primitives

    > > > may be found, as the definition seems to vary across papers.

    > >

    > > Perhaps what you're looking for is the "Joy manual", available on

    > > his site, or by typing "manual ." into the interpreter.

    >

    > hi brent

    >

    > i'm inclined to take the joy manual as the current standard

    > definition of the language, but if you look at some of the

    > other papers, you'll see that there are other, non-identical

    > lists of primitives given.

     Yes... hmm, maybe those are mostly enumerated in the "Standard library",

    which contains extra primitives constructed from the "core" ones.

     > btw, have you answered your original question about 'dip'?

     Oh, let's see... this question: (?)

      It is currently unknown to me if it is possible to construct "dip"

      in a similar way from "cons" instead of "cat" and "unit"

      (where it was constructed as: swap unit cat call)

    Nope... actually, I had totally forgotten about it :-)

    My guess is that it is not possible. One thing to be sure is

    that the sequence should not end in "cons call" because that is

    the same as just "call".

    To be specific, we'd have to pick a certain base that we're dealing

    with; I was thinking of {swap, dup, drop, call, cons}:

      [Y] [X] swap  ==  [X] [Y]

          [X] dup   ==  [X] [X]

          [X] drop  ==

          [X] call  ==  X

      [Y] [X] cons  ==  [[Y] X]

    And what we're trying to construct is "dip":

      [Y] [X] dip   ==  X [Y]

     > > - Brent Kerby ("iepos")

    > [stevan apter]

     - Brent Kerby ("iepos")