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