[stack] improved parallel combinator

John Nowak <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
I actually really like this one. No more weird pseudo-vector stuff.

Here are the semantics:

            S (| F |)  ==  S F
        S (| F , G |)  ==  S F { S G } peek
    S (| F , G , H |)  ==  S F { S G } peek { S H } peek
                       ..

Here are some examples:

                5 (| sq , neg |)  ==  25 -5
                 4 3 (| + , * |)  ==  7 12
            1 2 (| nip , drop |)  ==  2 1        ! same as 'swap'
    { 2 3 4 } (| rest , first |)  ==  { 3 4 } 2  ! same as 'unclip'

Here is the implementation:

    : infra-seq ( seq seq -- seq )
        [ [ with-datastack peek ] curry keep ] each drop ;
    : datastack-tail ( x -- x seq )
        [ datastack ] dip swap ;
    : parallel ( seq -- )
        datastack-tail [ unclip dip ] dip swap infra-seq ;

    ! "banana syntax" for 'parallel':
    ! (| F , G |) == { [ F ] [ G ] } parallel
    : |) ;
    : (| \ |)
        [ \ , 1array split [ >quotation ] map ] parse-literal
        \ parallel suffix ; parsing

For those not familiar with Factor:

             { x0 .. xN } peek  ==  xN
                { x S } unclip  ==  { S } x
                  [ F ] x slip  ==  F x
    { S } [ F ] with-datastack  ==  { S F }

The trick was realizing that the first quotation should be applied  
directly to the main stack. Lacking this, you'd need to explicitly  
indicate how many values to pass to each function (as with '2cleave',  
'3cleave', etc).

The only downside of this form compared to the previous one is that  
you need to explicitly group values if you want to return more than  
one from one of the functions (except for the first). I don't see this  
as a big problem.

- 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.