# Re: [stack] a lazy k (update)

## stevan apter — 2005-06-05 23:55:28

    a SLACK program consists of an expression followed by zero

    or more definitions:

        expression

         {definition}

         :

         {definition}

    a definition has the form

        {name arguments is expression

           {definition}

           :

           {definition}}

    a definition may contain references to definitions at its

    level or definitions it contains.  for example

        f x is g x

          {g x is if x=0 then 0 else h x-1}

          {h x is if x=0 then 0 else g x-1}

        f x is g h x+1

          {g y is y-3}

          {h z is z%2}

    a SLACK program is compiled into a binary tree in which all

    references to definitions and variables are eliminated.

    here's the stripped-down version of the (lazy) evaluator

    (no cache, no common-sub-expression elimination):

    X.S:{[f;g;x](A;(A;f;x);(A;g;x))}

    X.K:{[x;y](A;`I;x)}

    X.I:{[x]x}

    X.B:{[f;g;x](A;f;(A;g;x))}

    X.C:{[f;g;x](A;(A;f;x);g)}

    X.S_:{[c;f;g;x](A;(A;c;(A;f;x));(A;g;x))}

    X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    X.Y:{[f](A;f;(A;`Y;f))}

    X.U:{[f;z](A;(A;f;(A;H;z));(A;T;z))}

    Trace:0

    trace:{[t]if[Trace;`0:Trace$rep t;if[#0:`;Trace::0]]}

    eval:{[t](A~*:)red/t}

    red:{[t]trace t;step . t}

    step:{[a;b;c]

     :[(2#b)~(A;I)  ;func b[2][eval c]

       (2#b)~(A;O)  ;cond[b 2;c]

       (2#b)~(A;C)  ;cons[b 2]c

       b~H          ;eval c[1]2

       b~T          ;eval c 2

                     exec[left b]c]}

    exec:{[b;c]:[7=4:b;b[c];_n~b;c;A~*b;(A;b;c);b c]}

    left:{[b]:[A~*b;red b;b _in!X;X b;b]}

    func:{[t]:[7=4:t;(A;I;t);t]}

    cons:{[b;c](,eval b),eval c}

    cond:{[i;t;e]:[eval i;eval t;eval e]}

## sa@dfa.com — 2005-06-07 17:04:08

    a SLACK script is a text file containing zero or more SLACK

    programs (see below.)

    each program begins in column 1, and subordinate definitions

    are indented at least one position.  e.g.,

    [1 2;[3 4;5]]

    / comment

    hd [1 2;!-1]

    10 20 30@1

    7+[1 2;[3 4]]

    hd tl [1 2 ; 3 4 5]

    \

    stop executing when \ in column 1

    f g 3

     {f x is -x}

     {g x is !x}

    f 3

     {f x is g x}

     {g x is x+10}

    fac 5

     {fac n is if n=0 then 1 else n*fac n-1}

    f 3

     {f x is if x=0 then 0 else g x-1}

     {g x is if x=0 then 0 else f x-1}

    the interpreter executes each program and returns the

    results as a list.

    the cache is implemented, as are lazy lists.

    here's the eval, which is a bit larger (my previous

    implementations of hd and tl were incorrect.)

    / combinator rewrite rules

    X.S:{[f;g;x]p:S x;(A;(A;f;p);(A;g;p))}

    X.K:{[x;y](A;`I;x)}

    X.I:{[x]x}

    X.B:{[f;g;x](A;f;(A;g;x))}

    X.C:{[f;g;x](A;(A;f;x);g)}

    X.S_:{[c;f;g;x]p:S x;(A;(A;c;(A;f;p));(A;g;p))}

    X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    X.Y:{[f]p:S(A;`Y;f);(A;f;p)}

    X.U:{[f;z]p:S z;(A;(A;f;(A;H;p));(A;T;p))}

    S:{(A;G;:[x _in Z;Z?x;-1+#Z,:,x])}  / set cache

    G:{:Z[x]:lazy Z x}                  / get cache

    Trace:0

    trace:{[t]if[Trace;`0:(Trace>0),:/(-__abs Trace)$rep

    t;if[Trace<0;if[#0:`;Trace::0]]]}

    eval:{[t]Z::();strict t}      / eval (set cache, strict)

    red:{[t]trace t;step . t}     / reduce

    strict:(7=4:*:)red/           / strict evaluation

    lazy:(A~*:)red/               / lazy evaluation

    list:(~P~*:)red/              / lazy-list evaluation

    hd:{x 1}list@                 / car

    tl:{x 2}list@                 / cdr

    step:{[a;b;c]

     :[(2#b)~(A;I)  ;func b[2][strict c]       / primitive

       (2#b)~(A;O)  ;cond[b 2;c]               / conditional

       (2#b)~(A;C)  ;pair[b 2]c                / cons -> pair

       a~P          ;cons[b]c                  / make a list

       b~H          ;hd c                      / head of list

       b~T          ;tl c                      / tail of list

       A~*b         ;exec[red b]c              / application

       b _in!X      ;exec[X b]c                / combinator

                     exec[b]c]}                / apply primitive

    exec:{[b;c]:[7=4:b;b[c];A~*b;(A;b;c);b c]} / func or apply or index

    func:{[t]:[7=4:t;(A;I;t);t]}               / evaluate a primitive

    pair:{[b;c](A;`I;(P;b;c))}                 / create a pair

    cond:{[a;b;c]:[strict a;lazy b;lazy c]}    / nb: srict in condition

    cons:{[b;c](,strict b),strict c}           / create a list

    left to do:  common subexpression elimination, interactive

    console.

    concatenative@yahoogroups.com wrote on 06/05/2005 07:55:28 PM:

     > a SLACK program consists of an expression followed by zero

    > or more definitions:

    >

    >     expression

    >      {definition}

    >      :

    >      {definition}

    >

    > a definition has the form

    >

    >     {name arguments is expression

    >        {definition}

    >        :

    >        {definition}}

    >

    > a definition may contain references to definitions at its

    > level or definitions it contains.  for example

    >

    >     f x is g x

    >       {g x is if x=0 then 0 else h x-1}

    >       {h x is if x=0 then 0 else g x-1}

    >

    >     f x is g h x+1

    >       {g y is y-3}

    >       {h z is z%2}

    >

    > a SLACK program is compiled into a binary tree in which all

    > references to definitions and variables are eliminated.

    >

    > here's the stripped-down version of the (lazy) evaluator

    > (no cache, no common-sub-expression elimination):

    >

    > X.S:{[f;g;x](A;(A;f;x);(A;g;x))}

    > X.K:{[x;y](A;`I;x)}

    > X.I:{[x]x}

    > X.B:{[f;g;x](A;f;(A;g;x))}

    > X.C:{[f;g;x](A;(A;f;x);g)}

    > X.S_:{[c;f;g;x](A;(A;c;(A;f;x));(A;g;x))}

    > X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    > X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    > X.Y:{[f](A;f;(A;`Y;f))}

    > X.U:{[f;z](A;(A;f;(A;H;z));(A;T;z))}

    >

    > Trace:0

    > trace:{[t]if[Trace;`0:Trace$rep t;if[#0:`;Trace::0]]}

    >

    > eval:{[t](A~*:)red/t}

    > red:{[t]trace t;step . t}

    >

    > step:{[a;b;c]

    >  :[(2#b)~(A;I)  ;func b[2][eval c]

    >    (2#b)~(A;O)  ;cond[b 2;c]

    >    (2#b)~(A;C)  ;cons[b 2]c

    >    b~H          ;eval c[1]2

    >    b~T          ;eval c 2

    >                  exec[left b]c]}

    >

    > exec:{[b;c]:[7=4:b;b[c];_n~b;c;A~*b;(A;b;c);b c]}

    > left:{[b]:[A~*b;red b;b _in!X;X b;b]}

    > func:{[t]:[7=4:t;(A;I;t);t]}

    > cons:{[b;c](,eval b),eval c}

    > cond:{[i;t;e]:[eval i;eval t;eval e]}

    >

    >

    >

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

    >

## stevan apter — 2005-06-07 22:55:49

    common sub-expression elimination works nicely.

    example: the execution tree for the expression

        (!3)+!3

    is (*unicode alert*):

        show"(!3)+!3"

     ┌─────▀──────┐

     │            │

    `K      ┌─────▀─────┐

            │           │

         ┌──▀───┐     ┌─▀─┐

         │      │     │   │

        ┌▀┐   ┌─▀─┐  ┌▀┐  3

        │ │   │   │  │ │

       :: +  ┌▀┐  3 :: !:

             │ │

            :: !:

    before executing, we identify the two instances of

    the subtree for !3, cache the subtree, and replace

    each instance with a pointer to the cache.  when

    the pointer is executed the first time, it evaluates

    the subtree and replaces the cache with the result,

    as can be seen after executing:

        Z

     ,0 1 2

    (that is, !3 -> 0 1 2)

    the common subexpression elimination code:

    / cache common sub-expressions:

    leaves:{[t]:[@t;,();,/(!#t),/:'_f't[]]}

    nodes:{[p]{x@>#:'x}@?,/{(-1_1+!#x)#\:x}'p}

    paths:nodes leaves@

    cse:{[t]

     k:&(~(A;I)~2#)'d i[;0]j:&1<#:'i:=d:t ./:p:paths t

     {sub[;;y]. x}/[(();t);p i j k]}

    sub:{[z;t;p]

     q:(A;G;-1+#z,:,t .*p)

     t:{.[x;y;:;q]}/[t;p]

     (z;t)}

    i think it's worthwhile pointing out that the

    SLACK implementation is first-to-last wholly

    loop-free.

    i said earlier that i believe the SLACK compiler/

    evaluator is indifferent to the syntax of the

    source language.  the compiler expects a certain

    form of p-tree and produces an e-tree.  so any

    language which maps to the right kind of p-tree

    should work.  so, at some point, i'll implement a

    little joy parser to test that belief.

    i'd be interested in hearing from readers of this

    list who've implemented joy in haskell (i know

    there've been several), and who've retained or

    exploited haskell's innate laziness to advantage.

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

    From: <sa@...>

    To: <concatenative@yahoogroups.com>

    Sent: Tuesday, June 07, 2005 1:04 PM

    Subject: Re: [stack] a lazy k (update)

    > a SLACK script is a text file containing zero or more SLACK

    > programs (see below.)

    >

    > each program begins in column 1, and subordinate definitions

    > are indented at least one position.  e.g.,

    >

    > [1 2;[3 4;5]]

    >

    > / comment

    >

    > hd [1 2;!-1]

    >

    > 10 20 30@1

    >

    > 7+[1 2;[3 4]]

    >

    > hd tl [1 2 ; 3 4 5]

    >

    > \

    >

    > stop executing when \ in column 1

    >

    > f g 3

    >  {f x is -x}

    >  {g x is !x}

    >

    > f 3

    >  {f x is g x}

    >  {g x is x+10}

    >

    > fac 5

    >  {fac n is if n=0 then 1 else n*fac n-1}

    >

    > f 3

    >  {f x is if x=0 then 0 else g x-1}

    >  {g x is if x=0 then 0 else f x-1}

    >

    > the interpreter executes each program and returns the

    > results as a list.

    >

    > the cache is implemented, as are lazy lists.

    >

    > here's the eval, which is a bit larger (my previous

    > implementations of hd and tl were incorrect.)

    >

    > / combinator rewrite rules

    >

    > X.S:{[f;g;x]p:S x;(A;(A;f;p);(A;g;p))}

    > X.K:{[x;y](A;`I;x)}

    > X.I:{[x]x}

    > X.B:{[f;g;x](A;f;(A;g;x))}

    > X.C:{[f;g;x](A;(A;f;x);g)}

    > X.S_:{[c;f;g;x]p:S x;(A;(A;c;(A;f;p));(A;g;p))}

    > X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    > X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    > X.Y:{[f]p:S(A;`Y;f);(A;f;p)}

    > X.U:{[f;z]p:S z;(A;(A;f;(A;H;p));(A;T;p))}

    >

    > S:{(A;G;:[x _in Z;Z?x;-1+#Z,:,x])}  / set cache

    > G:{:Z[x]:lazy Z x}                  / get cache

    >

    > Trace:0

    > trace:{[t]if[Trace;`0:(Trace>0),:/(-__abs Trace)$rep

    > t;if[Trace<0;if[#0:`;Trace::0]]]}

    >

    > eval:{[t]Z::();strict t}      / eval (set cache, strict)

    >

    > red:{[t]trace t;step . t}     / reduce

    >

    > strict:(7=4:*:)red/           / strict evaluation

    > lazy:(A~*:)red/               / lazy evaluation

    > list:(~P~*:)red/              / lazy-list evaluation

    > hd:{x 1}list@                 / car

    > tl:{x 2}list@                 / cdr

    >

    > step:{[a;b;c]

    >  :[(2#b)~(A;I)  ;func b[2][strict c]       / primitive

    >    (2#b)~(A;O)  ;cond[b 2;c]               / conditional

    >    (2#b)~(A;C)  ;pair[b 2]c                / cons -> pair

    >    a~P          ;cons[b]c                  / make a list

    >    b~H          ;hd c                      / head of list

    >    b~T          ;tl c                      / tail of list

    >    A~*b         ;exec[red b]c              / application

    >    b _in!X      ;exec[X b]c                / combinator

    >                  exec[b]c]}                / apply primitive

    >

    > exec:{[b;c]:[7=4:b;b[c];A~*b;(A;b;c);b c]} / func or apply or index

    > func:{[t]:[7=4:t;(A;I;t);t]}               / evaluate a primitive

    > pair:{[b;c](A;`I;(P;b;c))}                 / create a pair

    > cond:{[a;b;c]:[strict a;lazy b;lazy c]}    / nb: srict in condition

    > cons:{[b;c](,strict b),strict c}           / create a list

    >

    > left to do:  common subexpression elimination, interactive

    > console.

    >

    > concatenative@yahoogroups.com wrote on 06/05/2005 07:55:28 PM:

    >

    > > a SLACK program consists of an expression followed by zero

    > > or more definitions:

    > >

    > >     expression

    > >      {definition}

    > >      :

    > >      {definition}

    > >

    > > a definition has the form

    > >

    > >     {name arguments is expression

    > >        {definition}

    > >        :

    > >        {definition}}

    > >

    > > a definition may contain references to definitions at its

    > > level or definitions it contains.  for example

    > >

    > >     f x is g x

    > >       {g x is if x=0 then 0 else h x-1}

    > >       {h x is if x=0 then 0 else g x-1}

    > >

    > >     f x is g h x+1

    > >       {g y is y-3}

    > >       {h z is z%2}

    > >

    > > a SLACK program is compiled into a binary tree in which all

    > > references to definitions and variables are eliminated.

    > >

    > > here's the stripped-down version of the (lazy) evaluator

    > > (no cache, no common-sub-expression elimination):

    > >

    > > X.S:{[f;g;x](A;(A;f;x);(A;g;x))}

    > > X.K:{[x;y](A;`I;x)}

    > > X.I:{[x]x}

    > > X.B:{[f;g;x](A;f;(A;g;x))}

    > > X.C:{[f;g;x](A;(A;f;x);g)}

    > > X.S_:{[c;f;g;x](A;(A;c;(A;f;x));(A;g;x))}

    > > X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    > > X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    > > X.Y:{[f](A;f;(A;`Y;f))}

    > > X.U:{[f;z](A;(A;f;(A;H;z));(A;T;z))}

    > >

    > > Trace:0

    > > trace:{[t]if[Trace;`0:Trace$rep t;if[#0:`;Trace::0]]}

    > >

    > > eval:{[t](A~*:)red/t}

    > > red:{[t]trace t;step . t}

    > >

    > > step:{[a;b;c]

    > >  :[(2#b)~(A;I)  ;func b[2][eval c]

    > >    (2#b)~(A;O)  ;cond[b 2;c]

    > >    (2#b)~(A;C)  ;cons[b 2]c

    > >    b~H          ;eval c[1]2

    > >    b~T          ;eval c 2

    > >                  exec[left b]c]}

    > >

    > > exec:{[b;c]:[7=4:b;b[c];_n~b;c;A~*b;(A;b;c);b c]}

    > > left:{[b]:[A~*b;red b;b _in!X;X b;b]}

    > > func:{[t]:[7=4:t;(A;I;t);t]}

    > > cons:{[b;c](,eval b),eval c}

    > > cond:{[i;t;e]:[eval i;eval t;eval e]}

    > >

    > >

    > >

    > >

    > >

    > >

    > > Yahoo! Groups Links

    > >

    > >

    > >

    > >

    > >

    > >

    > >

    >

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

## stevan apter — 2005-06-07 23:01:59

    oops - what a mess.  here's the ascii version of that

    last message:

    -----------

    common sub-expression elimination works nicely.

    example: the execution tree for the expression

        (!3)+!3

    is:

        show"(!3)+!3"

     +-----¯------+

     ¦            ¦

    `K      +-----¯-----+

            ¦           ¦

         +--¯---+     +-¯-+

         ¦      ¦     ¦   ¦

        +¯+   +-¯-+  +¯+  3

        ¦ ¦   ¦   ¦  ¦ ¦

       :: +  +¯+  3 :: !:

             ¦ ¦

            :: !:

    before executing, we identify the two instances of

    the subtree for !3, cache the subtree, and replace

    each instance with a pointer to the cache.  when

    the pointer is executed the first time, it evaluates

    the subtree and replaces the cache with the result,

    as can be seen after executing:

       Z

     ,0 1 2

    (that is, !3 -> 0 1 2)

    the common subexpression elimination code:

    / cache common sub-expressions:

    leaves:{[t]:[@t;,();,/(!#t),/:'_f't[]]}

    nodes:{[p]{x@>#:'x}@?,/{(-1_1+!#x)#\:x}'p}

    paths:nodes leaves@

    cse:{[t]

     k:&(~(A;I)~2#)'d i[;0]j:&1<#:'i:=d:t ./:p:paths t

     {sub[;;y]. x}/[(();t);p i j k]}

    sub:{[z;t;p]

     q:(A;G;-1+#z,:,t .*p)

     t:{.[x;y;:;q]}/[t;p]

     (z;t)}

    i think it's worthwhile pointing out that the

    SLACK implementation is first-to-last wholly

    loop-free.

    i said earlier that i believe the SLACK compiler/

    evaluator is indifferent to the syntax of the

    source language.  the compiler expects a certain

    form of p-tree and produces an e-tree.  so any

    language which maps to the right kind of p-tree

    should work.  so, at some point, i'll implement a

    little joy parser to test that belief.

    i'd be interested in hearing from readers of this

    list who've implemented joy in haskell (i know

    there've been several), and who've retained or

    exploited haskell's innate laziness to advantage.

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

    From: <sa@...>

    To: <concatenative@yahoogroups.com>

    Sent: Tuesday, June 07, 2005 1:04 PM

    Subject: Re: [stack] a lazy k (update)

    >

    >

    >

    >

    >

    > a SLACK script is a text file containing zero or more SLACK

    > programs (see below.)

    >

    > each program begins in column 1, and subordinate definitions

    > are indented at least one position.  e.g.,

    >

    > [1 2;[3 4;5]]

    >

    > / comment

    >

    > hd [1 2;!-1]

    >

    > 10 20 30@1

    >

    > 7+[1 2;[3 4]]

    >

    > hd tl [1 2 ; 3 4 5]

    >

    > \

    >

    > stop executing when \ in column 1

    >

    > f g 3

    >  {f x is -x}

    >  {g x is !x}

    >

    > f 3

    >  {f x is g x}

    >  {g x is x+10}

    >

    > fac 5

    >  {fac n is if n=0 then 1 else n*fac n-1}

    >

    > f 3

    >  {f x is if x=0 then 0 else g x-1}

    >  {g x is if x=0 then 0 else f x-1}

    >

    > the interpreter executes each program and returns the

    > results as a list.

    >

    > the cache is implemented, as are lazy lists.

    >

    > here's the eval, which is a bit larger (my previous

    > implementations of hd and tl were incorrect.)

    >

    > / combinator rewrite rules

    >

    > X.S:{[f;g;x]p:S x;(A;(A;f;p);(A;g;p))}

    > X.K:{[x;y](A;`I;x)}

    > X.I:{[x]x}

    > X.B:{[f;g;x](A;f;(A;g;x))}

    > X.C:{[f;g;x](A;(A;f;x);g)}

    > X.S_:{[c;f;g;x]p:S x;(A;(A;c;(A;f;p));(A;g;p))}

    > X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    > X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    > X.Y:{[f]p:S(A;`Y;f);(A;f;p)}

    > X.U:{[f;z]p:S z;(A;(A;f;(A;H;p));(A;T;p))}

    >

    > S:{(A;G;:[x _in Z;Z?x;-1+#Z,:,x])}  / set cache

    > G:{:Z[x]:lazy Z x}                  / get cache

    >

    > Trace:0

    > trace:{[t]if[Trace;`0:(Trace>0),:/(-__abs Trace)$rep

    > t;if[Trace<0;if[#0:`;Trace::0]]]}

    >

    > eval:{[t]Z::();strict t}      / eval (set cache, strict)

    >

    > red:{[t]trace t;step . t}     / reduce

    >

    > strict:(7=4:*:)red/           / strict evaluation

    > lazy:(A~*:)red/               / lazy evaluation

    > list:(~P~*:)red/              / lazy-list evaluation

    > hd:{x 1}list@                 / car

    > tl:{x 2}list@                 / cdr

    >

    > step:{[a;b;c]

    >  :[(2#b)~(A;I)  ;func b[2][strict c]       / primitive

    >    (2#b)~(A;O)  ;cond[b 2;c]               / conditional

    >    (2#b)~(A;C)  ;pair[b 2]c                / cons -> pair

    >    a~P          ;cons[b]c                  / make a list

    >    b~H          ;hd c                      / head of list

    >    b~T          ;tl c                      / tail of list

    >    A~*b         ;exec[red b]c              / application

    >    b _in!X      ;exec[X b]c                / combinator

    >                  exec[b]c]}                / apply primitive

    >

    > exec:{[b;c]:[7=4:b;b[c];A~*b;(A;b;c);b c]} / func or apply or index

    > func:{[t]:[7=4:t;(A;I;t);t]}               / evaluate a primitive

    > pair:{[b;c](A;`I;(P;b;c))}                 / create a pair

    > cond:{[a;b;c]:[strict a;lazy b;lazy c]}    / nb: srict in condition

    > cons:{[b;c](,strict b),strict c}           / create a list

    >

    > left to do:  common subexpression elimination, interactive

    > console.

    >

    > concatenative@yahoogroups.com wrote on 06/05/2005 07:55:28 PM:

    >

    > > a SLACK program consists of an expression followed by zero

    > > or more definitions:

    > >

    > >     expression

    > >      {definition}

    > >      :

    > >      {definition}

    > >

    > > a definition has the form

    > >

    > >     {name arguments is expression

    > >        {definition}

    > >        :

    > >        {definition}}

    > >

    > > a definition may contain references to definitions at its

    > > level or definitions it contains.  for example

    > >

    > >     f x is g x

    > >       {g x is if x=0 then 0 else h x-1}

    > >       {h x is if x=0 then 0 else g x-1}

    > >

    > >     f x is g h x+1

    > >       {g y is y-3}

    > >       {h z is z%2}

    > >

    > > a SLACK program is compiled into a binary tree in which all

    > > references to definitions and variables are eliminated.

    > >

    > > here's the stripped-down version of the (lazy) evaluator

    > > (no cache, no common-sub-expression elimination):

    > >

    > > X.S:{[f;g;x](A;(A;f;x);(A;g;x))}

    > > X.K:{[x;y](A;`I;x)}

    > > X.I:{[x]x}

    > > X.B:{[f;g;x](A;f;(A;g;x))}

    > > X.C:{[f;g;x](A;(A;f;x);g)}

    > > X.S_:{[c;f;g;x](A;(A;c;(A;f;x));(A;g;x))}

    > > X.B_:{[c;f;g;x](A;c;(A;f;(A;g;x)))}

    > > X.C_:{[c;f;g;x](A;(A;c;(A;f;x));g)}

    > > X.Y:{[f](A;f;(A;`Y;f))}

    > > X.U:{[f;z](A;(A;f;(A;H;z));(A;T;z))}

    > >

    > > Trace:0

    > > trace:{[t]if[Trace;`0:Trace$rep t;if[#0:`;Trace::0]]}

    > >

    > > eval:{[t](A~*:)red/t}

    > > red:{[t]trace t;step . t}

    > >

    > > step:{[a;b;c]

    > >  :[(2#b)~(A;I)  ;func b[2][eval c]

    > >    (2#b)~(A;O)  ;cond[b 2;c]

    > >    (2#b)~(A;C)  ;cons[b 2]c

    > >    b~H          ;eval c[1]2

    > >    b~T          ;eval c 2

    > >                  exec[left b]c]}

    > >

    > > exec:{[b;c]:[7=4:b;b[c];_n~b;c;A~*b;(A;b;c);b c]}

    > > left:{[b]:[A~*b;red b;b _in!X;X b;b]}

    > > func:{[t]:[7=4:t;(A;I;t);t]}

    > > cons:{[b;c](,eval b),eval c}

    > > cond:{[i;t;e]:[eval i;eval t;eval e]}

    > >

    > >

    > >

    > >

    > >

    > >

    > > Yahoo! Groups Links

    > >

    > >

    > >

    > >

    > >

    > >

    > >

    >

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

## sa@dfa.com — 2005-07-05 14:58:06

    my paper on SLACK has reached "first draft" stage:

          http://www.nsl.com/k/slack/slack.htm

    and a summary will eventually follow.  meanwhile, i

    continue to exercise the compiler to find its weak

    points.

    on a related front, work is underway on a parser

    front-end for joy (or something not too different

    from that language.)

    as you might expect, everything gets simpler:  the

    parser has fewer cases to manage, the compiler

    remains the same, and the reduction engine will

    see only a proper subset of the SLACK operators.