Re: [stack] adding construction to Joy-like languages

John Nowak <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
On Dec 30, 2008, at 8:41 AM, Stevan Apter wrote:

>> 2. FP has functions which, given a list, return a single element from
>> that list. Factor has no way (that I know of) to index into a stack
>> returning only the element selected.
>
> why limit yourself to a single element, or to indexing only at the
> top level of a list?

The type system, mainly. For indexing within a vector within another  
vector, you'd have to use something equivalent to Joy's "infra". For  
example:

    1 2 (3 (4 5)) [1st] infra 2nd
    1 2 (3 (4 5) 1st) 2nd
    1 2 (3 5) 2nd
    1 2 3

It's possible that some additional special form could be introduced to  
make such indexing a bit easier. For homogeneous vectors of  
indeterminate length, things could be done a bit differently. It's  
sort of like the difference between tuples and lists in something like  
ML; The former is tracked much more closely on the type level while  
the latter admits a much broader set of operations. Right now, I'm  
only dealing with the former.

> i'm not sure what the problem is, so my suggestions might be off-
> target.

I apologize for not explaining it well.

Essentially what I'm trying to do is come up with something like  
"cleave" for a concatenative language that behaves a bit better. To  
illustrate the current problem with the cleave family, take this  
example (where 'x' is an object and 'F' and 'G' are functions):

    x [F] [G] bi

In a language like Factor, it's hard to say much about this. It's  
unclear if 'F' or 'G' will need more values on the stack beyond the  
'x' that is provided. It's unclear how many values will be returned as  
a result. It's unclear if G will access any values produced by F. Etc.

What I want to be able to do for the above example is solve all of  
those problems. I want it to be clear that the 'x' provided is all F  
and G care about. I want it to be clear that F and G will not  
interact. I want it to be clear that the result will be two values.  
Finally, I want this all to be syntactically obvious; I do not want to  
have to employ the type system to do it.

This is already a solved issue in FP. For example:

    [F, G]:x   -- the construction of 'F' and 'G' applied to 'x'
               -- reduces to...
    <F:x, G:x> -- the list of 'F' and 'G' each applied to 'x'

Essentially, I was trying to add this form of construction to a  
concatenative language. My first attempt was as follows:

1. Limit the functions involved to only using the top element of the  
stack
2. Return the result of each function in its own stack

As a trivial example (where braces denote a stack):

    5 [sq] [dup] bi-construct
    {5 sq} {5 dup}
    {25} {5 5}

The problem with this is that I now have two stacks on the stack. To  
get at the 25, I need to manually pull the value out of the second  
stack. This makes the whole thing too awkward to use.

The solution I proposed was to replace the notion of a stack with the  
notion of a vector where a vector containing a single element is  
equivalent to the element it contains. Here's the same example using  
vectors:

    5 [sq] [dup] bi-construct
    (5) [sq] [dup] bi-construct
    (5 sq) (5 dup)
    (25) (5 5)
    25 (5 5)

Because '5 == (5)', I was able to use construction. Because '(25) ==  
25', I can now access the value without manually pulling it out of the  
stack. At the same time, the result of the other function which  
yielded two values is still nicely bundled up. I get all the  
guarantees I was after without the drudgery.

- John
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.