# Re: [stack] conk - concatened k

## stevan apter — 2000-06-11 01:44:52

    and here is the execution trace:

    k>1 trace

    k>10 [1 1] swap [0 [+] scan 1 drop reverse] scando flip first

    10

    10 [1 1]

    [1 1] 10

    [1 1] 10 [0 [+] scan 1 drop reverse]

    [[1 1] [2 1] [3 2] [5 3] [8 5] [13 8] [21 13] [34 21] [55 34] [89 55] [144 89]]

    [[1 2 3 5 8 13 21 34 55 89 144] [1 1 2 3 5 8 13 21 34 55 89]]

    [1 2 3 5 8 13 21 34 55 89 144]

    k>

    the k algorithm is:

        fib:{*+x(|+\)\1 1}

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

    From: stevan apter <apter@...>

    To: <concatenative@egroups.com>

    Sent: Saturday, June 10, 2000 5:28 PM

    Subject: [stack] conk - concatened k

    > as i thought, it wasn't much work to implement a concatenative

    > syntax for a substantial fragment of the k language (www.kx.com).

    > including the parser and comments, 157 lines and < 4k.

    >

    > here is conk's (non-recursive) fibonacci:

    >

    >     fib == [1 1] swap [0 [+] scan 1 drop reverse] scando flip first

    >     10 fib

    >  [1 2 3 5 8 13 21 34 55 89 144]

    >

    > conk.k will be available at www.kx.com/technical/contribs/stevan.html

    > sometime on monday.

    >

    >

    >

    >

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

    > Porsche Boxter. You and a friend. Nine dream days from

    > Napa Valley to Beverly Hills. Provided by CarsDirect.com.

    > Click to enter.

    > http://click.egroups.com/1/4882/6/_/_/_/960671964/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## stevan apter — 2000-06-12 13:25:36

    my second conk program deals with a problem which cropped up

    recently in programming a large monte-carlo simulation.  along

    each path in the simulation, a sequence of assignments must be

    computed.  initially, the statements must be ordered.  for

    example:

    some assignments, out of order:

    d:c+b

    c:-b

    e:d*a

    b:10

    a:20

    problem:  re-order to avoid value errors.

    k solution:  represent the statements as a dictionary s:

        s.d:`c`b

        s.c:,`b

        s.e:`d`a

        s.b:0#`

        s.a:0#`

    the k function is:

        order:{?|,/(?,/x@)\y}

        order[s;!s]

    `b`c`a`d`e

    i.e., compute b, then c, then a, then d, then e.

    in conk, start by creating the dictionary s:

        [[d[c b]][c[b]][e[d a]][b[]][a[]]]dict

    'dict' takes a list of symbol-value pairs and returns a

    dictionary.

        dup dom enlist cons

    'dom' takes a dictionary and returns a list of the symbols

    which form the handles of the dictionary.

    'enlist' is 'unitlist'.

    'disperse' takes a list at the top of the stack which has

    n items and places the n items at the top of the stack.

    'raze' takes a list and joins the items of the list to form

    a new list.

    'unique' takes a list and returns the unique items of the list

    'n take' takes the first n items of a list and returns a list

    containing those items.

    'scanconverge' takes a program and an item and keeps applying

    the program to its own result until either the original item

    is produced, or its result matches its input.  the sequence of

    results is returned as a list:

        [dup disperse at raze unique enlist join 2 take reverse]scanconverge

    the result is a list of pairs - [domain dictionary] - so:

        flip reverse first raze reverse

    'flip' is matrix transpose.

    this gives the desired result:

        [b c a d e]

    it would be interesting to see this problem solved in pure joy.

    in place of dictionaries, the set of assignments could be represented

    as a pure list.

## Louis Madon — 2000-06-13 01:20:04

    stevan apter wrote:

     >

    > my second conk program deals with a problem which cropped up

    > recently in programming a large monte-carlo simulation.  along

    > each path in the simulation, a sequence of assignments must be

    > computed.  initially, the statements must be ordered.  for

    > example:

    >

    > some assignments, out of order:

    >

    > d:c+b

    > c:-b

    > e:d*a

    > b:10

    > a:20

    >

    > problem:  re-order to avoid value errors.

     [..]

     > it would be interesting to see this problem solved in pure joy.

     Ok, I'll have a crack at it. This is a dependancy analysis problem and

    the usual way to solve it is topological sorting. Here is a solution

    using the reference version of Joy:

    topsort == cream [null] [pop] [dupd swap makestrainer map topsort

    concat] ifte;

    cream == [second null] split [firsts] dip;

    makestrainer == unitlist [unpair] swoncat [setdiff pair] concat;

    Doing,

      [[d[c b]][c[b]][e[d a]][b[]][a[]]] topsort

      gives [b a c d e] which meets the desired requirements.

    Note that I first tried writing topsort non-recursively using linrec as:

    topsort == cream [null] [pop] [dupd swap makestrainer map] [concat]

    linrec;

    This is a bit more elegant, but unfortunately Joy goes into an infinite

    gc loop - obviously a bug in the reference implementation :-(

    Anyway, the code above makes use of two auxillary definitions which are

    more generally useful than just for this problem. It would be useful to

    have them in a library, so I'm showing them here separately.

    firsts == [first] map;

    setdiff == [unitlist cons] cons map [unpair swap has not] filter firsts;

    'firsts' takes a list of lists and returns the first element of each

    list.

    'setdiff' is simply set difference. The second list elements are removed

    (if they exist) from the first list.

    Regarding efficiency, theres a much better (linear time) algorithm for

    topological sorting based on depth first search. However, it requires

    imperative features (to keep track of 'visited' nodes) and so can't be

    implemented in standard Joy. [BTW, I don't know K, but is it purely

    functional? If not, do they do anything special to try and make

    reasoning about the non-pure features any easier?]

    --

    Louis.

## stevan apter — 2000-06-13 13:05:32

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

    From: Louis Madon <madonl@...>

    To: <concatenative@egroups.com>

    Sent: Monday, June 12, 2000 9:20 PM

    Subject: Re: [stack] conk - concatened k

    thanks louis.  i'll try to dig in to both of your solutions later

    today or tomorrow.  right now, neither executes in my implementation,

    which probably means there are still a few bugs.

    >

    >

    > Regarding efficiency, theres a much better (linear time) algorithm for

    > topological sorting based on depth first search. However, it requires

    > imperative features (to keep track of 'visited' nodes) and so can't be

    > implemented in standard Joy. [BTW, I don't know K, but is it purely

    > functional? If not, do they do anything special to try and make

    > reasoning about the non-pure features any easier?]

    it isn't purely functional, although i'm not sure what would make

    it easier to reason about the non-pure features.

    the depth-first search algorithm in k goes:

        orderd:{[u;i]if[~B i;B[i]:1;u _f/:u i]}

    where B is a global boolean vector, B[i] = 1 if node i has been visited,

    and u is a list s.t. u[i] is a list of the nodes used by i.  the

    recursion u _f/:u i calls orderd on each node in u i.

    >

    > --

    > Louis.

    >

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

    > Great savings and lots more -- beMANY!

    > http://click.egroups.com/1/4114/6/_/_/_/960858910/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## wtanksley@bigfoot.com — 2000-06-13 16:49:37

    BTW, this is a little late -- Louis beat me to it :-).

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

     >'dict' takes a list of symbol-value pairs and returns a

    >dictionary.

     Any particular reason for the abbreviation?  I mean, is that k tradition?

    If there's no other reason, I really prefer to avoid abbreviations in

    libraries.  It's very easy to misspell or misundestand them.

     >    [dup disperse at raze unique enlist join 2 take

    >reverse]scanconverge

     What does 'at' mean?  How about 'join'?

    Wait, 'at' has to be dictionary lookup.  Ah, I think I see.

    I don't see the word itself -- is it:

     order == [dup disperse at raze unique enlist join 2 take

      reverse]scanconverge flip reverse first raze reverse.

     >it would be interesting to see this problem solved in pure joy.

    >in place of dictionaries, the set of assignments could be represented

    >as a pure list.

     Hmm, interesting question.  Let's see...

    We won't use dictionaries; instead we'll use a list structured like your

    definition of dictionaries (but I'll call it the dictionary).  We'll destroy

    the dictionary in the process of analysing it :-).

    'bs_differ' is defined as part of Joy's additional types; it's a set

    difference.

    This process will not terminate if there's a cyclic definition, i.e. (a=b;

    b=a).  Try not to do that.

     dependancies == rest first;

     addDefinition == first swap cons;

     seperateEmpties == [dependancies null] split;

     getDefinitionList == [swap] dip;

     updateDependancies == dependancies swap dup [bs_differ] dip;

     definePossibles == seperateEmpties getDefinitionList

                        [addDefinition] step swap

                        [updateDependancies] map

                         ;

     exhaust == [dup null not] while pop;

     order == [] swap [definePossibles] exhaust reverse.

    Fun.  Not as efficient as either of yours, I think.  It also doesn't

    terminate on certain inputs, whereas the k/conk version would have.  (I'm

    not sure about the topo sort-- would it terminate?)

    -Billy

## wtanksley@bigfoot.com — 2000-06-13 16:56:46

    From: Louis Madon [mailto:madonl@...]

     >Regarding efficiency, theres a much better (linear time) algorithm for

    >topological sorting based on depth first search. However, it requires

    >imperative features (to keep track of 'visited' nodes) and so can't be

    >implemented in standard Joy.

     Joy is almost completely imperative; the only exception is the definition

    language, where Joy attempts to imitate other functional/declarative

    languages in order to allow the author to ignore the system dictionary while

    analysing the system.

    Why wouldn't is be possible to have, for example, the 'first' of each node

    be a 'visited' marker?  Or if you need a central list of visited nodes, do

    like I did and keep them on the stack.

     >Louis.

     -Billy

## Louis Madon — 2000-06-13 21:28:38

    stevan apter wrote:

     > it isn't purely functional, although i'm not sure what would make

    > it easier to reason about the non-pure features.

     I know of at least three ways: by adding restrictions (eg. linear typing

    restricts you to at most one reference per mutable value), constructing

    the impure computation functionally at the meta-level (eg. Haskell

    Monads) or by increasing the amount of "structure" (eg. strongly typed

    non-castable pointers vs. void pointers).  Dynamic functions are

    currently my favorite approach though, they in efffect strongly type not

    only what is being pointed to but where you are pointing _from_;

    additionally they localise updates since the idea is that no other

    construct in the language is impure (and in proper ASMs DFs are

    first-order, ie, you can't pass them around as first-class values; I'm

    relaxing that restriction in JEL though I haven't yet thought through

    what the full implications might be).

     >

    > the depth-first search algorithm in k goes:

    >

    >     orderd:{[u;i]if[~B i;B[i]:1;u _f/:u i]}

    >

    > where B is a global boolean vector, B[i] = 1 if node i has been

    > visited,

    > and u is a list s.t. u[i] is a list of the nodes used by i.  the

    > recursion u _f/:u i calls orderd on each node in u i.

     Why make B global? Surely, this should be local?

    --

    Louis.

## Louis Madon — 2000-06-13 22:56:57

    wtanksley@... wrote:

     > >it would be interesting to see this problem solved in pure joy.

    > >in place of dictionaries, the set of assignments could be represented

    > >as a pure list.

    >

    > Hmm, interesting question.  Let's see...

    >

    > We won't use dictionaries; instead we'll use a list structured like

    > your

    > definition of dictionaries (but I'll call it the dictionary).  We'll

    > destroy

    > the dictionary in the process of analysing it :-).

    >

    > 'bs_differ' is defined as part of Joy's additional types; it's a set

    > difference.

     Oh, I didn't look there! I guess it helps to RTFM before rolling your

    own.

     >

    > This process will not terminate if there's a cyclic definition, i.e.

    > (a=b;

    > b=a).  Try not to do that.

     The code I posted yesterday has the same problem, not difficult to fix

    though - just requires a null list test after dependencies have been

    gathered.

     >

    > dependancies == rest first;

    > addDefinition == first swap cons;

    > seperateEmpties == [dependancies null] split;

    > getDefinitionList == [swap] dip;

    > updateDependancies == dependancies swap dup [bs_differ] dip;

    > definePossibles == seperateEmpties getDefinitionList

    >                     [addDefinition] step swap

    >                     [updateDependancies] map

    >                      ;

    >

    > exhaust == [dup null not] while pop;

    > order == [] swap [definePossibles] exhaust reverse.

    >

     This looks like the same approach I took, thoug I must say, yours is

    more readable. I think I need to break the habit of using terse naming

    as I'm used to doing in my C/Haskell stuff.  Psychologically, terse

    names make the code look "light weight" but thats deceptive - terse

    naming is actually harder to read.

    BTW, in 'exhaust' the dup (just before null) is redundant: the reason is

    that Joy executes the predicate tests in while, if, etc as nullary

    functions.  This is not documented anywhere (AFAIK) and it took me a

    while to realize that that is how its implemented. I do like this

    feature.

    BTW2, what input format did you use for the dictionary? I tried running

    '[[d[c b]][c[b]][e[d a]][b[]][a[]]] order' but that didn't work for me

    (I get an "aggregate paramater need for split" error).

     > Fun.  Not as efficient as either of yours, I think.  It also doesn't

    > terminate on certain inputs, whereas the k/conk version would have.

    > (I'm

    > not sure about the topo sort-- would it terminate?)

     No, but as I mentioned above, its easy to fix that. Regarding

    efficiency, its hard to say, your algorithm is very similar to mine, so

    I'd be suprised if performance differs much.

    --

    Louis.

## stevan apter — 2000-06-13 23:20:01

    >

    > >

    > > the depth-first search algorithm in k goes:

    > >

    > >     orderd:{[u;i]if[~B i;B[i]:1;u _f/:u i]}

    > >

    > > where B is a global boolean vector, B[i] = 1 if node i has been

    > > visited,

    > > and u is a list s.t. u[i] is a list of the nodes used by i.  the

    > > recursion u _f/:u i calls orderd on each node in u i.

    >

    > Why make B global? Surely, this should be local?

     again, insufficient coffee, since this piece of code doesn't, in fact,

    order formulas.  this one does:

        order:{[u;i]:[0>B i;'"loop: ",$i;if[~B i;B[i]:-1;u _f/:u[i]_dv i;B[i]:1;C,:i]]}

    B and C global, purely for speed (the application contains tens of

    thousands of formulas, and spending more than a fraction of second

    in this routine is unacceptable.)  however, it will be fun to revisit

    the problem with the aim of localizing the variables.

    thanks

     >

    > --

    > Louis.

    >

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

    > Get a NextCard Visa, in 30 seconds!

    > 1. Fill in the brief application

    > 2. Receive approval decision within 30 seconds

    > 3. Get rates as low as 2.9% Intro or 9.9% Fixed APR

    > http://click.egroups.com/1/5197/6/_/_/_/960931419/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## stevan apter — 2000-06-13 23:33:40

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

    From: <wtanksley@...>

    To: <concatenative@egroups.com>

    Sent: Tuesday, June 13, 2000 12:49 PM

    Subject: RE: [stack] conk - concatened k

    > BTW, this is a little late -- Louis beat me to it :-).

    >

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

    >

    > >'dict' takes a list of symbol-value pairs and returns a

    > >dictionary.

    >

    > Any particular reason for the abbreviation?  I mean, is that k tradition?

    > If there's no other reason, I really prefer to avoid abbreviations in

    > libraries.  It's very easy to misspell or misundestand them.

    ok

    >

    > >    [dup disperse at raze unique enlist join 2 take

    > >reverse]scanconverge

    >

    > What does 'at' mean?  How about 'join'?

    sorry, i didn't have time to document the conk words.  i've just

    used the k primitive names for all conk translations.  so 'join'

    is concatenation and 'at' is generalized indexing.

    >

    > Wait, 'at' has to be dictionary lookup.  Ah, I think I see.

    and list indexing and function application ... except there are

    no lambdas in conk.  ;-)

    >

    > I don't see the word itself -- is it:

    >

    >  order == [dup disperse at raze unique enlist join 2 take

    >   reverse]scanconverge flip reverse first raze reverse.

    this is as direct a translation as i can manage, modulo the

    stack manipulation stuff, of:

            ?|,/(?,/d@)\!d

    d is a dictionary, !d is a vector of the handles (entries) in d.

    read this:

        unique(reverse(raze(((unique raze d at)scanconverge)(domain d))))

    parenthesized to aid readability.

    [...]

    thanks billy

## stevan apter — 2000-06-13 23:36:48

    >

    > This looks like the same approach I took, thoug I must say, yours is

    > more readable. I think I need to break the habit of using terse naming

    > as I'm used to doing in my C/Haskell stuff.  Psychologically, terse

    > names make the code look "light weight" but thats deceptive - terse

    > naming is actually harder to read.

    >

     in a symbolic language like k, short names make the computational structure

    salient.  in general, the more i can see on a page, the better.  an ancient

    dispute -  i think you might be able to find it in one of the platonic

    dialogues.  ;-)

## Louis Madon — 2000-06-13 23:55:52

    wtanksley@... wrote:

     >

    > From: Louis Madon [mailto:madonl@...]

    > >Regarding efficiency, theres a much better (linear time) algorithm

    > for

    > >topological sorting based on depth first search. However, it requires

    > >imperative features (to keep track of 'visited' nodes) and so can't

    > be

    > >implemented in standard Joy.

    >

    > Joy is almost completely imperative; the only exception is the

    > definition

    > language, where Joy attempts to imitate other functional/declarative

    > languages in order to allow the author to ignore the system dictionary

    > while

    > analysing the system.

    >

     Sorry, I used too general a term, I should have said in-place update

    which is a certain kind of imperative feature that Joy doesn't have.

     > Why wouldn't is be possible to have, for example, the 'first' of each

    > node

    > be a 'visited' marker?  Or if you need a central list of visited

    > nodes, do

    > like I did and keep them on the stack.

     But then I don't see how setting the marker can be a constant time

    operation; changing it requires resplicing the newly created node back

    into the graph (which will affect all nodes back up to the root) - a

    logarithmic time operation. I guess I should have said, can't be

    implemented _as efficiently_ in standard Joy. [certainly, if you know

    that the graph is _guaranteed_ to have particular properties, eg it is a

    DAG, then you can probably improve the running time, but the

    conventional approach via in-place update is not senstive to such

    issues].

    --

    Louis.

## Louis Madon — 2000-06-14 00:47:37

    stevan apter wrote:

     >

    > >

    > > This looks like the same approach I took, thoug I must say, yours is

    > > more readable. I think I need to break the habit of using terse

    > naming

    > > as I'm used to doing in my C/Haskell stuff.  Psychologically, terse

    > > names make the code look "light weight" but thats deceptive - terse

    > > naming is actually harder to read.

    > >

    >

    > in a symbolic language like k, short names make the computational

    > structure

    > salient.  in general, the more i can see on a page, the better.  an

    > ancient

    > dispute -  i think you might be able to find it in one of the platonic

    > dialogues.  ;-)

    >

     This got me thinking, it would be very easy to make Joy a symbolic

    language too; just give every standard Joy function a unique symbol and

    make the concatenation operator (space) optional between symbols (since

    there would be no ambiguity), eg:

    foo:%^$*^&#D*&^E bar*U*&^Y baz^

    Thats technically a trivial change to the language syntax, yet it lets

    you write super-terse code. I suspect most people wouldn't like it

    though and it would look like line noise to anyone not familiar with the

    symbols.  However, the terse and normal syntax could coexist and be

    automatically transformable to either style.

    What about going the other way: is it possible to imagine a non-symbolic

    K? What might a snippet of such code look like? I think that might

    provide some insight into how similar Joy and K might be (especially for

    me since I don't grok K symbols).

    --

    Louis.

## wtanksley@bigfoot.com — 2000-06-14 00:46:40

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

     >> This looks like the same approach I took, thoug I must say, yours is

    >> more readable. I think I need to break the habit of using

    >> terse naming

    >> as I'm used to doing in my C/Haskell stuff.  Psychologically, terse

    >> names make the code look "light weight" but thats deceptive - terse

    >> naming is actually harder to read.

    >in a symbolic language like k, short names make the

    >computational structure

    >salient.  in general, the more i can see on a page, the

    >better.  an ancient

    >dispute -  i think you might be able to find it in one of the platonic

    >dialogues.  ;-)

     I actually have to agree with you -- the long names I used were long mainly

    because I didn't take the time to find a short synonym.  Brevity is the soul

    of wit.

    However, there's an interesting difference between k and Joy here.  In k,

    the computational structure is expressed as part of the language, and the

    names can get in the way.  In Joy, the language doesn't have the capacity to

    express computational structure, so the names have to serve instead.

    Thus, the epigram: "Every Forth programmer owns a well-used thesaurus."  I

    just don't have my thesaurus nearby me.

    I'm looking forward to polymorphic static typing, since that will remove the

    need to explicitly specify type as part of the name.

    -Billy

## wtanksley@bigfoot.com — 2000-06-14 00:50:25

    From: Louis Madon [mailto:madonl@...]

     >wtanksley@... wrote:

    >> From: Louis Madon [mailto:madonl@...]

    >> >it requires

    >> >imperative features (to keep track of 'visited' nodes) and so can't

    >> >be implemented in standard Joy.

    >> Joy is almost completely imperative; the only exception is the

    >> definition

    >> language, where Joy attempts to imitate other functional/declarative

    >> languages in order to allow the author to ignore the system

    >> dictionary while analysing the system.

    >Sorry, I used too general a term, I should have said in-place update

    >which is a certain kind of imperative feature that Joy doesn't have.

     Ah, my mistake.  Yes, absolutely.

    ASMs accurately model execution in the presence of in-place updates, so I

    look forward to your language.

    Interestingly, ASM rules fire in parallel while concatenative words execute

    in serial.  How do you plan to resolve the distinction?

     >Louis.

     -Billy

## wtanksley@bigfoot.com — 2000-06-14 00:53:17

    From: Louis Madon [mailto:madonl@...]

     >wtanksley@... wrote:

    >BTW2, what input format did you use for the dictionary? I tried running

    >'[[d[c b]][c[b]][e[d a]][b[]][a[]]] order' but that didn't work for me

    >(I get an "aggregate paramater need for split" error).

     My apologies -- I don't have a Joy system running here, so I coded that in

    my mind.  I expect it to be buggy, and I should have mentioned that.  Sorry.

    The input you're using should have been correct.  I'll debug it when I

    respond to your message, possibly tomorrow (but no promises :-).

     >Louis.

     -Billy

## stevan apter — 2000-06-14 01:07:27

    >

    > What about going the other way: is it possible to imagine a non-symbolic

    > K? What might a snippet of such code look like? I think that might

    > provide some insight into how similar Joy and K might be (especially for

    > me since I don't grok K symbols).

     nonsymbolic conk:

        order == [dup disperse at raze unique enlist join 2 take reverse]

                  scanconverge flip reverse first raze reverse

    symbolic conk, following k convention:  f: is the monadic case

    / // etc. to differentiate varieties of over, scan, &c.

    some operations have no analogue in k.

        raze == ,: [] [,]/

        order == [dup disperse @2 raze ?: ,: , 2 # |:]\\ +: |: *: raze |:

    symbolic k:

        order:{?|,/(?,/x@)\!x}

    non-symbolic k:

        order:{unique(reverse(raze(((unique raze x at)scanconverge)(domain x))))}

    i've parenthesized the non-symbolic version, to indicate (explicitly)

    the order of execution.

    partly, conk is motivated by curiosity:  to what extent does syntax,

    a symbolic lexicon, and appplicative semantics contribute to productivity

    in k?

     >

    >

    > --

    > Louis.

    >

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

    > Accurate impartial advice on everything from laptops to table saws.

    > http://click.egroups.com/1/4634/6/_/_/_/960943371/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## stevan apter — 2000-06-14 01:10:17

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

    From: <wtanksley@...>

    To: <concatenative@egroups.com>

    Sent: Tuesday, June 13, 2000 8:46 PM

    Subject: RE: [stack] conk - concatened k

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

    >

    > >> This looks like the same approach I took, thoug I must say, yours is

    > >> more readable. I think I need to break the habit of using

    > >> terse naming

    > >> as I'm used to doing in my C/Haskell stuff.  Psychologically, terse

    > >> names make the code look "light weight" but thats deceptive - terse

    > >> naming is actually harder to read.

    >

    > >in a symbolic language like k, short names make the

    > >computational structure

    > >salient.  in general, the more i can see on a page, the

    > >better.  an ancient

    > >dispute -  i think you might be able to find it in one of the platonic

    > >dialogues.  ;-)

    >

    > I actually have to agree with you -- the long names I used were long mainly

    > because I didn't take the time to find a short synonym.  Brevity is the soul

    > of wit.

    ;-)

    >

    > However, there's an interesting difference between k and Joy here.  In k,

    > the computational structure is expressed as part of the language, and the

    > names can get in the way.  In Joy, the language doesn't have the capacity to

    > express computational structure, so the names have to serve instead.

    right - your example finally clarified what you've been calling

    'factoring'.  the meanings of the names you chose bear the weight

    of the absent syntactic structure.  very nice (although i can't get

    the damned thing to run!!  the manual and the 'atomic programs' paper

    disagree about the order of items on the stack for 'while'.  did you

    get a chance to run your order routine?

    >

    > Thus, the epigram: "Every Forth programmer owns a well-used thesaurus."  I

    > just don't have my thesaurus nearby me.

    >

    > I'm looking forward to polymorphic static typing, since that will remove the

    > need to explicitly specify type as part of the name.

    >

    > -Billy

    >

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

    > eGroups members: $60 in FREE calls! Join beMANY!

    > And pay less each month for long distance.

    > http://click.egroups.com/1/4122/6/_/_/_/960943540/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## Louis Madon — 2000-06-14 01:19:19

    wtanksley@... wrote:

     > ASMs accurately model execution in the presence of in-place updates,

    > so I

    > look forward to your language.

    >

    > Interestingly, ASM rules fire in parallel while concatenative words

    > execute

    > in serial.  How do you plan to resolve the distinction?

     Not quite true. ASM rules fire when their guard conditions are met. This

    is just a way to do sequencing without having to introduce a

    full-fledged language. In Jel, the guards are unneccesary since Joy code

    does the sequencing. The only thing that is missing is a way to execute

    a bunch of updates in parallel; One possibility is that a special

    combinator is provided (like i) except that it takes a quotation

    containing only updates and executes them "simultaneously".  Note that,

    so far, I've been concentrating on the type system and so haven't

    thought these issues through fully.

    --

    Louis.

## wtanksley@bigfoot.com — 2000-06-14 01:29:17

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

     >From: <wtanksley@...>

    >> However, there's an interesting difference between k and Joy

    >> here.  In k,

    >> the computational structure is expressed as part of the

    >> language, and the

    >> names can get in the way.  In Joy, the language doesn't have

    >> the capacity to

    >> express computational structure, so the names have to serve instead.

    >right - your example finally clarified what you've been calling

    >'factoring'.  the meanings of the names you chose bear the weight

    >of the absent syntactic structure.

     Yes, that's an excellent way to put it.  And that is one of the primary

    goals of factoring: to make the code tell its own story.  A secondary goal

    is to make the code smaller by factoring out commonly used chunks of

    functionality.

    The fact that the language uses no local variables makes it trivial to

    refactor functions while preserving their behavior.  While building that

    demo I did quite a bit of refactoring -- in fact, when I started building it

    I didn't even know how I would do it.  It took shape under my hands.

     >very nice (although i can't get

    >the damned thing to run!!  the manual and the 'atomic programs' paper

    >disagree about the order of items on the stack for 'while'.  did you

    >get a chance to run your order routine?

     You've hit the exact problem -- I haven't tested it.

    -Billy

## Louis Madon — 2000-06-14 01:52:04

    stevan apter wrote:

     > non-symbolic k:

    >

    >     order:{unique(reverse(raze(((unique raze x at)scanconverge)(domain

    > x))))}

     I'm a bit confused by this part:

    raze (((unique raze x at)scanconverge) (domain x))

    Why does raze take two arguments; I thought it takes a list and joins

    all the items in it to form a new list. Why is scanconverge being passed

    as an argument to a function computed by unique? Sorry, I must be

    misinterpreting this ...

    --

    Louis.

## Louis Madon — 2000-06-14 04:50:00

    Louis Madon wrote:

     > topsort == cream [null] [pop] [dupd swap makestrainer map] [concat]

    > linrec;

    >

    > This is a bit more elegant, but unfortunately Joy goes into an

    > infinite

    > gc loop - obviously a bug in the reference implementation :-(

     I was wrong, its my code not the Joy implementation!! linrec ofcourse

    won't recurse back to topsort but will build a new anonymous recursive

    function.  Here's a non-recursive definition based on the x combinator

    that does work (and with slightly better naming):

    topsort ==

      [swap sepEmpties

        [null]

        [pop popd]

        [dupd swap mkDepUpd map rolldown x concat]

        ifte

       ] x;

    mkDepUpd == unitlist [unpair] swoncat [setdiff pair] concat;

    sepEmpties == [second null] split [firsts] dip;

    --

    Louis.

## stevan apter — 2000-06-14 10:57:48

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

    From: Louis Madon <madonl@...>

    To: <concatenative@egroups.com>

    Sent: Tuesday, June 13, 2000 9:52 PM

    Subject: Re: [stack] conk - concatened k

    > stevan apter wrote:

    > > non-symbolic k:

    > >

    > >     order:{unique(reverse(raze(((unique raze x at)scanconverge)(domain

    > > x))))}

    >

    > I'm a bit confused by this part:

    >

    > raze (((unique raze x at)scanconverge) (domain x))

    >

    > Why does raze take two arguments; I thought it takes a list and joins

    > all the items in it to form a new list. Why is scanconverge being passed

    > as an argument to a function computed by unique? Sorry, I must be

    > misinterpreting this ...

        scanconverge takes the composition (unique raze x at) and

        derives a function which is repeatedly applied to (domain x)

        until the result is the same twice in a row (or the result

        matches the initial input).  the result is a list of all

        the results.  that list is razed. ...

        the categorial structure (see below) is:

            iv(((iv iv n tv)a)(iv n)

        where iv is intransitive verb, tv is transitive verb, a

        is adverb, and n is noun.  because of the binding-strengths

        of the categories, it can be written

            iv (iv iv n tv)a iv n

        here is the precis of k syntax i posted a few weeks ago:

    > we recognize three syntax categories:  noun, verb, and adverb.

    >

    > there are exactly 20 verbs:

    >

    >     ~ ! @ # $ % ^ & * _ - + = | : < , > . ?

    >

    > each verb can be monadic, in which case it is prefixed to its

    > noun:

    >

    >     ^x

    >

    > or dyadic, in which case it is written infix:

    >

    >     x^y

    >

    > there is no precedence.

    >

    > there are six adverbs:

    >

    >     ' \ / ': /: \:

    >

    > an adverb is suffixed to its verb or noun:

    >

    >     +/

    >     -':

    >     p\

    >

    > verbs take nouns to make nouns; adverbs take verbs and nouns to

    > make verbs.

    >

    > the parsing rules are given in two tables.  one table gives the

    > binding strengths between categories:

    >

    >  n n 1

    >  n v 3

    >  n a 4

    >  v n 2

    >  v v 1

    >  v a 4

    >

    > the other gives the result of binding two categories:

    >

    >  n n -> n        / application

    >  n v -> v        / curry

    >  n a -> v        / modify noun

    >  v n -> n        / monadic application

    >  v v -> v        / composition

    >  v a -> v        / modify verb

    >

    > parsing is simple:  scan from the right; when a drop in binding

    > strength occurs, bind the pair at that position and replace it

    > with the category of the result.

    >

    > nouns are datatypes.  in k, there are exactly 8:

    >

    >     int

    >     float

    >     byte

    >     symbol

    >     dictionary

    >     null

    >     lambda

    >     list

    >

    >

    > --

    > Louis.

    >

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

    > Win a trip to Vegas for you and 20 friends, $15,000 and a suite at

    > Bellagio for New Year's, courtesy of Expedia.com. Or win 2 roundtrip

    > tickets anywhere in the U.S. given away daily. Click for a chance to win.

    > http://click.egroups.com/1/5293/6/_/_/_/960947228/

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

    >

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

    > concatenative-unsubscribe@egroups.com

    >

    >

    >

    >

## wtanksley@bigfoot.com — 2000-06-14 22:26:03

    From: Louis Madon [mailto:madonl@...]

     >wtanksley@... wrote:

    >> ASMs accurately model execution in the presence of in-place updates,

    >> so I

    >> look forward to your language.

    >> Interestingly, ASM rules fire in parallel while concatenative words

    >> execute in serial.  How do you plan to resolve the distinction?

    >Not quite true. ASM rules fire when their guard conditions are

    >met. This

    >is just a way to do sequencing without having to introduce a

    >full-fledged language. In Jel, the guards are unneccesary

    >since Joy code does the sequencing.

     Ah, true.  That's what was confusing me.

     >The only thing that is missing is a way to execute

    >a bunch of updates in parallel; One possibility is that a special

    >combinator is provided (like i) except that it takes a quotation

    >containing only updates and executes them "simultaneously".  Note that,

    >so far, I've been concentrating on the type system and so haven't

    >thought these issues through fully.

     An interesting point is that niladic functions (fns with no stack effect)

    can be executed in any order.  Because of this, you can model parallelism by

    using functions which are niladic with respect to the system stack -- for

    example, functions which act on some other stack.

    In Forth, this would be cone using some kind of BEGIN word, which set up a

    state; a task-loader word, which placed the tasks ready to go; and an END

    word, which executed the tasks in parallel and unloaded the state when they

    were done.  Thus, only the ordering of the BEGIN and END would be relevant

    to the Forthlike language.

    BEGIN Task: 1 oneUpdate Task: 0 anotherUpdate END

    In Joy, I believe we'd want to use quotations, as you've said: since the

    language supplies some syntax, we might as well use it.

    [ [1 oneUpdate] [0 anotherUpdate] ] Parallel

     >Louis.

     -Billy