concatenative thread on "lambda the ultimate"
stevan apter — 2005-08-16 11:20:37
William Tanksley, Jr — 2005-08-17 04:05:04
stevan apter <
sa@...> wrote:
> the standard moves and counter-moves:
> http://lambda-the-ultimate.org/node/view/900
Hmm. I'm surprised to see a long argument about how painful using the
stack is, and nobody mentioning the concept of dataflow. The "stack
shufflers" aren't merely a low-level hinderance; they're also :) a
high-level expression of explicit dataflow control. People claiming
that concatenative languages are low-level because the expose the
stack haven't noticed that the stack is invisible... Not exposed. It's
implicit.
-Billy
Chris Double — 2005-08-17 04:15:54
On Tue, 16 Aug 2005 21:05:04 -0700, "William Tanksley, Jr"
> People claiming that concatenative languages are low-level because the
> expose the stack haven't noticed that the stack is invisible... Not
> exposed. It's implicit.
Most of the complaints seem to center around the stack words not being
part of the problem domain, so make the code harder to read/understand.
It is therefore low level (by their definition). I don't really disagree
with their point of view, as when doing lots of stack manipulation it
can seem low level at times.
Chris.
William Tanksley, Jr — 2005-08-17 04:41:22
Chris Double <
chris.double@...> wrote:
> On Tue, 16 Aug 2005 21:05:04 -0700, "William Tanksley, Jr"
> > People claiming that concatenative languages are low-level because the
> > expose the stack haven't noticed that the stack is invisible... Not
> > exposed. It's implicit.
> Most of the complaints seem to center around the stack words not being
> part of the problem domain, so make the code harder to read/understand.
> It is therefore low level (by their definition). I don't really disagree
> with their point of view, as when doing lots of stack manipulation it
> can seem low level at times.
It certainly can. I admit it. But it's not, in general. In general,
you're making your dataflow explicit -- and your dataflow IS part of
your problem (not just a low level detail). Yes, it makes you think. I
claim that the thinking is good for you and for your problem. Once you
find a dataflow that looks good in code, it'll also run well.
It's not low-level -- but it's perfectly compatible with it, unlike
most other concepts the high-level languages seem to like.
> Chris.
-Billy
Chris Double — 2005-08-17 05:01:47
On Tue, 16 Aug 2005 21:41:22 -0700, "William Tanksley, Jr"
<
wtanksleyjr@...> said:
> Yes, it makes you think. I claim that the thinking is good for you and
> for your problem. Once you find a dataflow that looks good in code,
> it'll also run well.
I very much agree with this. When programming in Factor I think about
how to organise the code a lot more than in other languages. And as a
result I often get better, more correct, code out of it.
Chris.
--
Chris Double
chris.double@...
sa@dfa.com — 2005-08-17 19:10:32
i've been meaning to do this for a while. playing with jot
pushed me to do something about it.
in the languages we've been discussing, everything is a unary
function: stack -> stack. in what i'm calling 'x', everything
is a unary function: function -> function.
the initial state is the identity function.
a literal is a function which takes the state and produces
a new function. that function, when evaluated, evaluates
the state it took as an argument, which typically returns
a list (stack), and pushes the literal on to it. e.g. 2
takes the state and returns a function which, when evaluated,
evaluates the state passed to 2 and pushes 2 onto it.
i've implemented, just for demo purposes, dup swap pop i dip
and all the k primitives.
example:
e(2;3;4;(+;*);`i)
,14
which in joy is
2 3 4 [+ *] i
e should produce, modulo differences in the primitives, the same
result as joy. e takes the result of evaluation, which is a
function, and executes it. the inner function, which produces
the functional input to e is more basic. with some format-sugar
to make it more readable (the actual object is rather ugly), we
have:
o a(2;3;4;(+;*);`i)
i[[[[[;2];3];4];(+;*)]]
[;2] composes 2 with the identity function, which is composed
with 3, which is composed with 4, which is composed with the
quotation (+;*), which is composed with i.
the a function takes no time, and can't fail. it just builds
the composition.
when the resulting composition is executed, the result is ,14.
Narcoleptic Electron — 2005-08-19 18:13:02
On 8/17/05,
sa@... <
sa@...> wrote:
> in the languages we've been discussing, everything is a unary
> function: stack -> stack. in what i'm calling 'x', everything
> is a unary function: function -> function.
>
> the initial state is the identity function.
>
> a literal is a function which takes the state and produces
> a new function. that function, when evaluated, evaluates
> the state it took as an argument, which typically returns
> a list (stack), and pushes the literal on to it. e.g. 2
> takes the state and returns a function which, when evaluated,
> evaluates the state passed to 2 and pushes 2 onto it.
What is the exact definition of "state" here?
> i've implemented, just for demo purposes, dup swap pop i dip
> and all the k primitives.
>
> example:
>
> e(2;3;4;(+;*);`i)
> ,14
>
> which in joy is
>
> 2 3 4 [+ *] i
>
> e should produce, modulo differences in the primitives, the same
> result as joy. e takes the result of evaluation, which is a
> function, and executes it. the inner function, which produces
> the functional input to e is more basic. with some format-sugar
> to make it more readable (the actual object is rather ugly), we
> have:
>
> o a(2;3;4;(+;*);`i)
> i[[[[[;2];3];4];(+;*)]]
>
> [;2] composes 2 with the identity function, which is composed
> with 3, which is composed with 4, which is composed with the
> quotation (+;*), which is composed with i.
>
> the a function takes no time, and can't fail. it just builds
> the composition.
>
> when the resulting composition is executed, the result is ,14.
I don't understand. It seems to me that this function->function
paradigm applies to Joy as well: the stack that it receives as input
can be considered a composition of the functions that produced that
stack, and the function that is returned is the input function
composed with the new function.
For example:
2 3 +
results in the following:
- Compose the identity function with the "2" function.
- Compose the "identity o 2" function with the "3" function.
- Compose the "identity o 2 o 3" function with the "+" function.
- Execute the resulting function.
Narcoleptic Electron — 2005-08-19 18:29:35
More clarification on my question...
On 8/19/05, Narcoleptic Electron <narcoleptic.electron@...> wrote:
> On 8/17/05, sa@... <sa@...> wrote:
> > in the languages we've been discussing, everything is a unary
> > function: stack -> stack. in what i'm calling 'x', everything
> > is a unary function: function -> function.
> >
> > the initial state is the identity function.
> >
> > a literal is a function which takes the state and produces
> > a new function. that function, when evaluated, evaluates
> > the state it took as an argument, which typically returns
> > a list (stack), and pushes the literal on to it. e.g. 2
> > takes the state and returns a function which, when evaluated,
> > evaluates the state passed to 2 and pushes 2 onto it.
>
> What is the exact definition of "state" here?
>
> > i've implemented, just for demo purposes, dup swap pop i dip
> > and all the k primitives.
> >
> > example:
> >
> > e(2;3;4;(+;*);`i)
> > ,14
> >
> > which in joy is
> >
> > 2 3 4 [+ *] i
> >
> > e should produce, modulo differences in the primitives, the same
> > result as joy. e takes the result of evaluation, which is a
> > function, and executes it. the inner function, which produces
> > the functional input to e is more basic. with some format-sugar
> > to make it more readable (the actual object is rather ugly), we
> > have:
> >
> > o a(2;3;4;(+;*);`i)
> > i[[[[[;2];3];4];(+;*)]]
> >
> > [;2] composes 2 with the identity function, which is composed
> > with 3, which is composed with 4, which is composed with the
> > quotation (+;*), which is composed with i.
> >
> > the a function takes no time, and can't fail. it just builds
> > the composition.
> >
> > when the resulting composition is executed, the result is ,14.
>
> I don't understand. It seems to me that this function->function
> paradigm applies to Joy as well: the stack that it receives as input
> can be considered a composition of the functions that produced that
> stack, and the function that is returned is the input function
> composed with the new function.
>
> For example:
>
> 2 3 +
>
> results in the following:
> - Compose the identity function with the "2" function.
> - Compose the "identity o 2" function with the "3" function.
> - Compose the "identity o 2 o 3" function with the "+" function.
> - Execute the resulting function.
I wasn't very clear here.
Here is my understanding of applying the function->function idea to
the Joy code "2 3 +":
- Function "2" takes the stack as input and returns the stack with 2
pushed onto it.
- Function "3" takes the stack as input and returns the stack with 3
pushed onto it.
When executed after function "2", you get the initial stack with 2 and
3 pushed onto it.
When composed with function "2", you get a function that produces the
initial stack with 2 and 3 pushed onto it.
- Function "+" returns the stack with the top two items popped, and
the sum pushed.
When executed after function "2 o 3", you get the initial stack with 5
pushed onto it.
When composed with function "2 o 3", you get a function that produces
the initial stack with 5 pushed onto it.
The resulting composed function is "2 o 3 o +", which when executed,
takes a stack and pushes 5 onto it.
Is this not the same thing as your language?
stevan apter — 2005-08-19 21:43:03
----- Original Message -----
From: "Narcoleptic Electron" <narcoleptic.electron@...>
To: <concatenative@yahoogroups.com>
Sent: Friday, August 19, 2005 2:29 PM
Subject: Re: [stack] type-lifted joy
More clarification on my question...
On 8/19/05, Narcoleptic Electron <narcoleptic.electron@...> wrote:
> On 8/17/05, sa@... <sa@...> wrote:
> > in the languages we've been discussing, everything is a unary
> > function: stack -> stack. in what i'm calling 'x', everything
> > is a unary function: function -> function.
> >
> > the initial state is the identity function.
> >
> > a literal is a function which takes the state and produces
> > a new function. that function, when evaluated, evaluates
> > the state it took as an argument, which typically returns
> > a list (stack), and pushes the literal on to it. e.g. 2
> > takes the state and returns a function which, when evaluated,
> > evaluates the state passed to 2 and pushes 2 onto it.
>
> What is the exact definition of "state" here?
>
> > i've implemented, just for demo purposes, dup swap pop i dip
> > and all the k primitives.
> >
> > example:
> >
> > e(2;3;4;(+;*);`i)
> > ,14
> >
> > which in joy is
> >
> > 2 3 4 [+ *] i
> >
> > e should produce, modulo differences in the primitives, the same
> > result as joy. e takes the result of evaluation, which is a
> > function, and executes it. the inner function, which produces
> > the functional input to e is more basic. with some format-sugar
> > to make it more readable (the actual object is rather ugly), we
> > have:
> >
> > o a(2;3;4;(+;*);`i)
> > i[[[[[;2];3];4];(+;*)]]
> >
> > [;2] composes 2 with the identity function, which is composed
> > with 3, which is composed with 4, which is composed with the
> > quotation (+;*), which is composed with i.
> >
> > the a function takes no time, and can't fail. it just builds
> > the composition.
> >
> > when the resulting composition is executed, the result is ,14.
>
> I don't understand. It seems to me that this function->function
> paradigm applies to Joy as well: the stack that it receives as input
> can be considered a composition of the functions that produced that
> stack, and the function that is returned is the input function
> composed with the new function.
>
> For example:
>
> 2 3 +
>
> results in the following:
> - Compose the identity function with the "2" function.
> - Compose the "identity o 2" function with the "3" function.
> - Compose the "identity o 2 o 3" function with the "+" function.
> - Execute the resulting function.
I wasn't very clear here.
Here is my understanding of applying the function->function idea to
the Joy code "2 3 +":
- Function "2" takes the stack as input and returns the stack with 2
pushed onto it.
there's is no stack. 2 takes the identity function and returns
a function which, when evaluated, appends 2 to the empty list.
write that function as [;2] (just to give it a name).
- Function "3" takes the stack as input and returns the stack with 3
pushed onto it.
3 takes [;2] and returns a function which, when evaluated, appends 3
to the result of evaluating [;2]. write that function as [[;2];3].
When executed after function "2", you get the initial stack with 2 and
3 pushed onto it.
When composed with function "2", you get a function that produces the
initial stack with 2 and 3 pushed onto it.
- Function "+" returns the stack with the top two items popped, and
the sum pushed.
+ takes [[;2];3] and returns a function which, when evaluated, takes
the last two elements of the list-result of evaluating [[;2];3], adds
them, and appends the result to the list you get from dropping the
last two elements. write that function as +[[;2];3].
When executed after function "2 o 3", you get the initial stack with 5
pushed onto it.
When composed with function "2 o 3", you get a function that produces
the initial stack with 5 pushed onto it.
The resulting composed function is "2 o 3 o +", which when executed,
takes a stack and pushes 5 onto it.
Is this not the same thing as your language?
i suppose you could think of x as compiling the input program
to a function which, when evaluated, returns what joy would
return when evaluating the same input program. joy and x are
extensionally equivalent. x just breaks evaluation into two
parts: construction of a function, and then evaluation of
that function. i haven't really had time to explore the
implications of this approach. it may come to nothing.
Yahoo! Groups Links