Matt Hellige | 1 Feb 2010 03:40

Re: [stack] function "adjoinment"?

 

On Sun, Jan 31, 2010 at 5:22 PM, John Nowak <john <at> johnnowak.com> wrote:
>
>
>
> We're familiar with the notion of function composition:
>
> (a -> b) -> (b -> c) -> (a -> c)
>
> However, is anyone familiar with a notion of function "adjoinment"?
> Given a function F that takes a tuple A to a tuple B, and a function G
> that takes a tuple C to a tuple D, the adjoinment of F and G would be
> a function that takes the concatenation of A and B to the
> concatenation of C and D. In other words:
>
> (a -> b) -> (c -> d) -> (a++b -> c++d)
> where ++ is concatenation and a,b,c,d are tuples/stacks
>

This reminds me of the *** operator in Haskell's Arrow library, which,
when specialized to the (->) arrow, has type (a->c) -> (b->c) ->
(a,a') -> (b,b'). You can use this to do something similar, and with
isomorphisms (a,(b,c)) <=> ((a,b),c), you can treat it like a more
general concatenation version. The special syntactic sugar for arrows
hides the tuple plumbing and makes this reasonably pleasant, but of
course Haskell's type system doesn't actually allow us to abstract
over tuples of arbitrary length.

I wonder if it would be possible to type this operator in a system of
extensible records like Daan Leijen's Morrow? That would be a neat
trick.

Finally, it also reminds me of operads. I've speculated a bit about a
general syntax for operadic composition, but don't really have
anything useful to say.

Matt

__._,_.___
.

__,_._,___
chris glur | 1 Feb 2010 14:31
Picon

Re: [stack] An Overlooked Paradigm in Functional Programming

 

> That's a lousy excuse for refusing to accept an answer to
> your problem. Just because you did no research doesn't mean
> there's no answer.

We seem to have lost each other completely ?
The author defined the factorial function in one short line of near english;
and then gave the multi-step joy interpretation.
Since my aim is to REDUCE mental load, it's irrelevant WHAT the finer
considerations of his joy-translation may be, because I don't want
to transform conceptual simplicity into complexity.
For all I know his joy-translation may have error/s, but that's
irrelevant. I merely pasted it to show how he's transformed simplicity
into complexity.

> Your specific goal *seems* to be to program in a low-level
> non-concatenative language and a high-level concatenative
> language. Since that goal is reversed from anyone else's I've
> ever met, I'm mildly interested -- I like contrarian thinking
> (that's why I'm studying concatenative languages).

I'll give a real-life example:
for part of a task, I needed the list of pid/S with the open file
'on mc'.
An existing function called lsof shows a zillion lines, typically:-
mc 3499 root txt REG 3,14 519624 375343 /usr/bin/mc

Since all I want is [each]: (3499, /usr/bin/mc) pair, I merely pass it
[NB the use of "it" to lambda-like eliminate IDs] through filters which:
1. show only the lines which have "/mc"
2 show only the part of the lines with the 2nd field [the 3499] and the
last field.

So there are 3 'library available' BIG functions:
= lsof [list open files]
= grep "/mc" [ but show only lines with "/mc"]
= cut <something> [but show only the wanted part of the lines]

I don't WANT to know how these, no doubt complex, functions work.
They are constructed by a 'proper language' - as you call "low level".
And the the cat-like just does:
lsof | grep "/mc" | cut <as required>

So altho' cat-like is no good for the real heavy-lifting, it's good
to chain/pipe existing functions together to do the hi-level tasks.

== Chris Glur.

On 1/31/10, William Tanksley, Jr <wtanksleyjr <at> gmail.com> wrote:
> chris glur <crglur <at> gmail.com> wrote:
>
>> > The absurdity of MANUALLY translating the 1-line pseudocode
>> > to joy, when a simple/immediate algol-like compilation is
>> > available tells much?
>> ]That's not even a remotely fair translation as it's not recursive like
>> ]the example. The straight-forward recursive function is as such:
>> I MIGHT analyse your code in the future, but:
>> I merely PASTED the joy-author's ample 1-line pseudocode and HIS
>> joy version.
>>
>
> That's a lousy excuse for refusing to accept an answer to your problem. Just
> because you did no research doesn't mean there's no answer.
>
> I won't follow your NEW argument about Haskell etc. on the going
>> nowhere [because it's fun] journey. Can't someone answer MY question/s?
>> I've got a specific goal and am NOT just playing 'look ma no hands' !
>
>
> Your specific goal *seems* to be to program in a low-level non-concatenative
> language and a high-level concatenative language. Since that goal is
> reversed from anyone else's I've ever met, I'm mildly interested -- I like
> contrarian thinking (that's why I'm studying concatenative languages).
>
> It so happens that there's plenty of solutions to your specific problem,
> even though they don't match your specific question.
>
> -Wm
>
>
> [Non-text portions of this message have been removed]
>
>

__._,_.___
.

__,_._,___
chris glur | 1 Feb 2010 14:33
Picon

Re: [stack] An Overlooked Paradigm in Functional Programming

 

> That's a lousy excuse for refusing to accept an answer to
> your problem. Just because you did no research doesn't mean
> there's no answer.

We seem to have lost each other completely ?
The author defined the factorial function in one short line of near english;
and then gave the multi-step joy interpretation.
Since my aim is to REDUCE mental load, it's irrelevant WHAT the finer
considerations of his joy-translation may be, because I don't want
to transform conceptual simplicity into complexity.
For all I know his joy-translation may have error/s, but that's
irrelevant. I merely pasted it to show how he's transformed simplicity
into complexity.

> Your specific goal *seems* to be to program in a low-level
> non-concatenative language and a high-level concatenative
> language. Since that goal is reversed from anyone else's I've
> ever met, I'm mildly interested -- I like contrarian thinking
> (that's why I'm studying concatenative languages).

I'll give a real-life example:
for part of a task, I needed the list of pid/S with the open file
'on mc'.
An existing function called lsof shows a zillion lines, typically:-
mc 3499 root txt REG 3,14 519624 375343 /usr/bin/mc

Since all I want is [each]: (3499, /usr/bin/mc) pair, I merely pass it
[NB the use of "it" to lambda-like eliminate IDs] through filters which:
1. show only the lines which have "/mc"
2 show only the part of the lines with the 2nd field [the 3499] and the
last field.

So there are 3 'library available' BIG functions:
= lsof [list open files]
= grep "/mc" [ but show only lines with "/mc"]
= cut <something> [but show only the wanted part of the lines]

I don't WANT to know how these, no doubt complex, functions work.
They are constructed by a 'proper language' - as you call "low level".
And the the cat-like just does:
lsof | grep "/mc" | cut <as required>

So altho' cat-like is no good for the real heavy-lifting, it's good
to chain/pipe existing functions together to do the hi-level tasks.

== Chris Glur.

On 1/31/10, William Tanksley, Jr <wtanksleyjr <at> gmail.com> wrote:
> chris glur <crglur <at> gmail.com> wrote:
>
>> > The absurdity of MANUALLY translating the 1-line pseudocode
>> > to joy, when a simple/immediate algol-like compilation is
>> > available tells much?
>> ]That's not even a remotely fair translation as it's not recursive like
>> ]the example. The straight-forward recursive function is as such:
>> I MIGHT analyse your code in the future, but:
>> I merely PASTED the joy-author's ample 1-line pseudocode and HIS
>> joy version.
>>
>
> That's a lousy excuse for refusing to accept an answer to your problem. Just
> because you did no research doesn't mean there's no answer.
>
> I won't follow your NEW argument about Haskell etc. on the going
>> nowhere [because it's fun] journey. Can't someone answer MY question/s?
>> I've got a specific goal and am NOT just playing 'look ma no hands' !
>
>
> Your specific goal *seems* to be to program in a low-level non-concatenative
> language and a high-level concatenative language. Since that goal is
> reversed from anyone else's I've ever met, I'm mildly interested -- I like
> contrarian thinking (that's why I'm studying concatenative languages).
>
> It so happens that there's plenty of solutions to your specific problem,
> even though they don't match your specific question.
>
> -Wm
>
>
> [Non-text portions of this message have been removed]
>
>

__._,_.___
.

__,_._,___
William Tanksley, Jr | 1 Feb 2010 15:33
Picon

Re: [stack] function "adjoinment"?

 

Matt Hellige <matt <at> immute.net> wrote:

> John Nowak <john <at> johnnowak.com> wrote:
> > We're familiar with the notion of function composition:
> > However, is anyone familiar with a notion of function "adjoinment"?
> > Given a function F that takes a tuple A to a tuple B, and a function G
> > that takes a tuple C to a tuple D, the adjoinment of F and G would be
> > a function that takes the concatenation of A and B to the
> > concatenation of C and D. In other words:
> > (a -> b) -> (c -> d) -> (a++b -> c++d)
> > where ++ is concatenation and a,b,c,d are tuples/stacks
>

I'm so bad at reading this kind of notation. But I think I see what you're
describing.

I wonder if it would be possible to type this operator in a system of
> extensible records like Daan Leijen's Morrow? That would be a neat
> trick.

Hmm... That's very interesting. I'd not noticed that one "fly by" on
lambda-the-ultimate. And this is a particularly interesting twisting of
Leijen: if I read you correctly, you're suggesting making all stack
functions take the same number of arguments, and then special-casing each
one by extending its record.

Given that practical concatenative languages tend to have style guidelines
that say "no more than 7 arguments per function", it's actually vaguely
conceivable that this would work (actually, I've never seen a style
guideline that says 7; they tend to say 3, as 7 is the utter limit of human
memory). Whatever limit you choose, you'd have to provide means for
overriding that limit.

Finally, it also reminds me of operads. I've speculated a bit about a
> general syntax for operadic composition, but don't really have
> anything useful to say.

It does indeed look like operad theory might be useful here. I've never seen
that before, so I'll leave it up to you -- the intros I found are _very_
mathematical.

Matt

-Wm

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

__._,_.___
.

__,_._,___
john | 1 Feb 2010 16:04
Gravatar

Re: [stack] function "adjoinment"?

 

"William Tanksley, Jr" <wtanksleyjr <at> gmail.com> wrote:

> John Nowak <john <at> johnnowak.com> wrote:

>> (a -> b) -> (c -> d) -> (a++b -> c++d)
>> where ++ is concatenation and a,b,c,d are tuples/stacks
>
> I'm so bad at reading this kind of notation. But I think I see what
you're
> describing.

Might've helped if I described it correctly. I meant:

(a -> b) -> (c -> d) -> (a++c -> b++d)

Or, to put it another way, if composition is this:
____
|____|
|____|

Then adjoinment is this:
____ ____
|____|____|

Really "concatenation" is a much better term for this than adjoinment
considering the input tuples are necessarily concatenated to be passed to
such a function... but using that term here is likely a bad idea.

I have a *very* tentative sketch of some ideas here; it wasn't written to
be made public, but if anyone wants to look at my notes, go for it:

http://johnnowak.com/heap/vis.txt

- jn

__._,_.___
.

__,_._,___
William Tanksley, Jr | 1 Feb 2010 16:09
Picon

Re: [stack] An Overlooked Paradigm in Functional Programming

 

chris glur <crglur <at> gmail.com> wrote:

> > That's a lousy excuse for refusing to accept an answer to
> > your problem. Just because you did no research doesn't mean
> > there's no answer.
> We seem to have lost each other completely ?
> The author defined the factorial function in one short line of near
> english;
> and then gave the multi-step joy interpretation.
>

You're talking about Manfred's Joy paper posted at
http://www.latrobe.edu.au/philosophy/phimvt/joy/j02maf.html. Manfred's paper
wasn't trying to express factorial in the simplest manner possible, nor in
the best way to express the English; rather, it's a "tour de force", to use
the author's own words about the program you quoted, intended only to show
the most primitive breakdown of the program's operation for tutorial
purposes. It's much like reading a .NET CIL dump and concluding that C# is
not suitable for programming in-the-large.

Manfred himself explains this immediately after the section you quote: "Of
course this program is a *tour de force*, it is ugly and inefficient. With
more suitable combinators much crisper and more efficient programs can be
written." He suggests using "primrec", as Nowak did, to produce the program
"[1] [*] primrec"; he also explains how high-level concepts would increase
the actual efficiency of the program by reducing the amount of data moving
and copying.

Yet you take that out of context to "prove" that all concatenative programs
are messy and nasty, when in fact all you've proven is that low-level
operations are low-level.

Since my aim is to REDUCE mental load, it's irrelevant WHAT the finer
> considerations of his joy-translation may be, because I don't want
> to transform conceptual simplicity into complexity.
>

That doesn't make sense. The reason he wrote the program dictates why it's
messy and low-level -- because he wanted to expose the low-level details of
the implementation.

> Your specific goal *seems* to be to program in a low-level
> > non-concatenative language and a high-level concatenative
> > language. Since that goal is reversed from anyone else's I've
> > ever met, I'm mildly interested -- I like contrarian thinking
> > (that's why I'm studying concatenative languages).
> I'll give a real-life example:
> Since all I want is [each]: (3499, /usr/bin/mc) pair, I merely pass it
> [NB the use of "it" to lambda-like eliminate IDs] through filters which:
>

You ARE aware that lambda creates IDs, right? It doesn't eliminate them.

So there are 3 'library available' BIG functions:
> = lsof [list open files]
> = grep "/mc" [ but show only lines with "/mc"]
> = cut <something> [but show only the wanted part of the lines]
> I don't WANT to know how these, no doubt complex, functions work.
> They are constructed by a 'proper language' - as you call "low level".
> And the the cat-like just does:
> lsof | grep "/mc" | cut <as required>
>

That's usually called a "compositional" language, in existing terminology.
There's nothing particularly concatenative about it; compositional pipe
languages usually support only one pipe at a time, whereas a concatenative
language has as many data streams as you want to push on the stack.
Concatenative languages also don't use an operator to denote composition,
preferring the syntax of juxtaposition (and hence making concatenation map
to composition, whence the name 'concatenative').

> So altho' cat-like is no good for the real heavy-lifting, it's good
> to chain/pipe existing functions together to do the hi-level tasks.

Compositional languages are typically not used to build complex features, as
you say; but concatenative languages _are_.

== Chris Glur.

-Wm

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

__._,_.___
.

__,_._,___
Matt Hellige | 1 Feb 2010 20:39

Re: [stack] function "adjoinment"?

 

On Mon, Feb 1, 2010 at 8:33 AM, William Tanksley, Jr
<wtanksleyjr <at> gmail.com> wrote:
>
> Matt Hellige <matt <at> immute.net> wrote:
>
> I wonder if it would be possible to type this operator in a system of
> > extensible records like Daan Leijen's Morrow? That would be a neat
> > trick.
>
> Hmm... That's very interesting. I'd not noticed that one "fly by" on
> lambda-the-ultimate. And this is a particularly interesting twisting of
> Leijen: if I read you correctly, you're suggesting making all stack
> functions take the same number of arguments, and then special-casing each
> one by extending its record.

Yes, this is what I'm suggesting. But I only just thought of it as I
was reading the original email in this thread, so I'm not really sure
whether it would be possible and haven't really thought it through,
let alone tried it. The stack effect system of languages like Cat,
though, always reminded me of a kind of row polymorphism, so I've had
the inkling before.

Matt

__._,_.___
.

__,_._,___
john | 1 Feb 2010 21:04
Gravatar

Re: [stack] function "adjoinment"?

 

On Mon, 1 Feb 2010 13:39:26 -0600, Matt Hellige <matt <at> immute.net> wrote:

> Yes, this is what I'm suggesting. But I only just thought of it as I
> was reading the original email in this thread, so I'm not really sure
> whether it would be possible and haven't really thought it through,
> let alone tried it. The stack effect system of languages like Cat,
> though, always reminded me of a kind of row polymorphism, so I've had
> the inkling before.

If you make use of the fact that almost all first-order functions have
a fixed arity (e.g. 3 -> 2) except for bizarre functions like 'clear',
you can type things similar to Factor's smart combinators that handle
things like stack concatenation. You just need a tiered approach where
your combinators are not themselves first-class values and only have
first-order functions provided to them. This lets you have types like
the following for function "concatenation":

fn-cat : (A -> B, C -> D) -> A C -> B D

The only requirement for this to work is that rows are introduced before
(i.e. "to the left of") the point they are used in a concatenation. For
example, instantiating the above function with a function of type
'R int -> R int' and a function of type 'R string int -> R char' would
yield a function of type 'R int string int -> R int char'.

Another example is concatenating first-class stacks; the only requirement
is that two first-order functions need to be supplied -- once for each
stack -- and then you can assemble the appropriate function "magically":

stack-cat : (A -> B, C -> D) -> R {A} {C} -> R {B++D}

This is all a bit cleaner if first order functions are not lifted to
operate on stacks of >= N size (where N is their input arity), but rather
on stacks of *exactly* N size, aka N-tuples. Doing this eliminates the
need to magically "unlift" functions and make them no longer row
polymorphic. This is the system I briefly describe in that "vis.txt"
document I linked to: http://johnnowak.com/heap/vis.txt

I should note that the flatness of concatenating inputs and outputs, as
opposed to the pairing done in the Arrow for -> in Haskell, lends itself
much better to a visual representation.

- jn

P.S. Emailing very quickly from work. Apologies if the above is unclear
(or worse).

__._,_.___
.

__,_._,___
chris glur | 2 Feb 2010 05:02
Picon

Re: [stack] An Overlooked Paradigm in Functional Programming

 

Can someone add value to my query/idea that 'perhaps cat-like is
effective/productive
in using pre-existing functions'. I'm only interested in productivety
increases, which
IMO come mostly by managing complexity ie. reducing the cognative
load; that's why
I found <the German-uni article> appropriate. Pity that THAT blog
needs a pasword.

Perhaps http://concatenative.org/wiki/view/Staapl
is talking about 'layered' system/s: like cat-like using pre-existing functions;
but at this stage of life, I'm not interested in 'playing cross word puzzles',
which seems the motivation of many contributors here.

On 2/1/10, William Tanksley, Jr <wtanksleyjr <at> gmail.com> wrote:
> chris glur <crglur <at> gmail.com> wrote:
>
>> > That's a lousy excuse for refusing to accept an answer to
>> > your problem. Just because you did no research doesn't mean
>> > there's no answer.
>> We seem to have lost each other completely ?
>> The author defined the factorial function in one short line of near
>> english;
>> and then gave the multi-step joy interpretation.
>>
>
> You're talking about Manfred's Joy paper posted at
> http://www.latrobe.edu.au/philosophy/phimvt/joy/j02maf.html. Manfred's paper
> wasn't trying to express factorial in the simplest manner possible, nor in
> the best way to express the English; rather, it's a "tour de force", to use
> the author's own words about the program you quoted, intended only to show
> the most primitive breakdown of the program's operation for tutorial
> purposes. It's much like reading a .NET CIL dump and concluding that C# is
> not suitable for programming in-the-large.
>
> Manfred himself explains this immediately after the section you quote: "Of
> course this program is a *tour de force*, it is ugly and inefficient. With
> more suitable combinators much crisper and more efficient programs can be
> written." He suggests using "primrec", as Nowak did, to produce the program
> "[1] [*] primrec"; he also explains how high-level concepts would increase
> the actual efficiency of the program by reducing the amount of data moving
> and copying.
>
> Yet you take that out of context to "prove" that all concatenative programs
> are messy and nasty, when in fact all you've proven is that low-level
> operations are low-level.
>
> Since my aim is to REDUCE mental load, it's irrelevant WHAT the finer
>> considerations of his joy-translation may be, because I don't want
>> to transform conceptual simplicity into complexity.
>>
>
> That doesn't make sense. The reason he wrote the program dictates why it's
> messy and low-level -- because he wanted to expose the low-level details of
> the implementation.
>
>> Your specific goal *seems* to be to program in a low-level
>> > non-concatenative language and a high-level concatenative
>> > language. Since that goal is reversed from anyone else's I've
>> > ever met, I'm mildly interested -- I like contrarian thinking
>> > (that's why I'm studying concatenative languages).
>> I'll give a real-life example:
>> Since all I want is [each]: (3499, /usr/bin/mc) pair, I merely pass it
>> [NB the use of "it" to lambda-like eliminate IDs] through filters which:
>>
>
> You ARE aware that lambda creates IDs, right? It doesn't eliminate them.
>
> So there are 3 'library available' BIG functions:
>> = lsof [list open files]
>> = grep "/mc" [ but show only lines with "/mc"]
>> = cut <something> [but show only the wanted part of the lines]
>> I don't WANT to know how these, no doubt complex, functions work.
>> They are constructed by a 'proper language' - as you call "low level".
>> And the the cat-like just does:
>> lsof | grep "/mc" | cut <as required>
>>
>
> That's usually called a "compositional" language, in existing terminology.
> There's nothing particularly concatenative about it; compositional pipe
> languages usually support only one pipe at a time, whereas a concatenative
> language has as many data streams as you want to push on the stack.
> Concatenative languages also don't use an operator to denote composition,
> preferring the syntax of juxtaposition (and hence making concatenation map
> to composition, whence the name 'concatenative').
>
>
>> So altho' cat-like is no good for the real heavy-lifting, it's good
>> to chain/pipe existing functions together to do the hi-level tasks.
>
>
> Compositional languages are typically not used to build complex features, as
> you say; but concatenative languages _are_.
>
> == Chris Glur.
>
>
> -Wm
>
>
> [Non-text portions of this message have been removed]
>
>

__._,_.___
.

__,_._,___
William Tanksley, Jr | 2 Feb 2010 06:04
Picon

Re: [stack] An Overlooked Paradigm in Functional Programming

 

chris glur <crglur <at> gmail.com> wrote:

> Can someone add value to my query/idea that 'perhaps cat-like is
> effective/productive in using pre-existing functions'.

I haven't seemed to be able to add the value you're looking for, so good
luck. I hope you come up with some interesting ideas.

I'm only interested in productivety increases, which
> IMO come mostly by managing complexity ie. reducing the cognative
> load;

If productivity truly is your main goal, you might consider being a little
more open to other possible factors contributing to productivity. For
example, the things that make a large team productive are not the things
that make a single person productive. This is why Java is so successful with
huge websites, and so unpleasant for personal projects. Anyone can slap
together a website for Python; but to merely get started with Java requires
you to choose between many competing frameworks for a million little parts
of the language, all of which have a million little configuration choices --
a large team has a specialist for each area, so the team can do the best
possible thing... the one person can't possibly figure out the best thing,
and will usually just pull some boilerplate code off the web.

Aside from the question of whether there are other ways to increase
productivity, the ways in which one manages complexity also matter. Compare
the solution in Java to the solution in Ruby -- and then look at Arc's
theory. (Arc's theory is that productivity is directly related to the
shortness of the natural solution in the language.)

Figuring out what's actually going on to cause productivity is a hard, hard
question... I hope you contribute to answering it someday.

Perhaps http://concatenative.org/wiki/view/Staapl
> is talking about 'layered' system/s: like cat-like using pre-existing
> functions;
> but at this stage of life, I'm not interested in 'playing cross word
> puzzles',
> which seems the motivation of many contributors here.
>

Playing with puzzles is sometimes useful, if the puzzles have never been
solved. We all have a part to play, if we're willing to do the work to play
it.

-Wm

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

__._,_.___
.

__,_._,___

Gmane