# "tick" stack shuffling notation

## John Nowak — 2008-03-10 02:17:15

    Here's a silly idea for another stack shuffling notation. The idea is

    that the top of the stack is always 'z', the element below is 'y', the

    element below that is 'x', and so on. The notation specifies the

    result of the shuffle, but *not* the precondition.

    It is assumes that all variables above the lowest one used were

    initially on the stack. In other words, if you write '`x', it is

    assumed the input stack was 'xyz', so '`x' is the same as '2drop'.

    This causes a problem for certain words like 'nip' (which can't be

    expressed with one shuffle), but most work quite well.

    Hopefully you're using monospace fonts in your email client.

    SHUFFLE         MNEMONIC        TICK

    z--             drop            `y

    yz--            2drop           `x

    xyz--           3drop           `w

    yz--z           nip             `zy `y

    xyz--z          2nip            `zxy `x

    z--zz           dup             `zz

    z--zzz          dup dup         `zzz

    yz--yzyz        2dup            `yzyz

    yz--yzyzyz      3dup            `yzyzyz

    yz--yyz         dupd            `yyz

    yz--yzy         over            `yzy

    xyz--xyzx       pick            `xyzx

    yz--zyz         tuck            `zyz

    yz--zy          swap            `zy

    xyz--yxz        swapd           `yxz

    xyz--zyx        spin            `zyx

    xyz--yzx        rot             `yzx

    xyz--zxy        -rot            `zxy

    wxyz--xyzw      roll            `xyzw

    wxyz--zwxy      -roll           `zwxy

    - John

## Daniel Ehrenberg — 2008-03-10 05:04:52

    In Factor, this can be implemented as a simple extension to the

    shufflers vocab. It took a little while for me to figure out exactly

    how to do the translation, but I worked it out eventually. The key

    word there is tick-shuffle>string. Below, I pasted the modified source

    code. (It's not very polished.) To allow the operations you've pasted,

    you need to write the following line:

    TICK-SHUFFLE: wxyz 6

    To use syntax like abc-bac for swapd, you can write the following:

    SHUFFLE: abc 3

    before code that uses these shuffling operators. I'm not sure how much

    I like the first notation, though. You're wrong; this notation does

    have a single-word nip operation; it's `xz.

    See, this is why arbitrary syntax extension like Factor has is so

    awesome: because you can do whatever you want. Strictly speaking, this

    doesn't really extend the syntax much, it just goes and defines all

    possible shufflers. But this is impossible in Scheme or Haskell.

    Dan

    ----

    USING: kernel sequences words math math.functions arrays

    shuffle quotations parser math.parser strings namespaces

    splitting effects sequences.lib combinators.lib ;

    IN: shufflers

    : shuffle>string ( names shuffle -- string )

        swap [ [ nth ] curry map ] curry map

        first2 "-" swap 3append >string ;

    : tick-shuffle>string ( names shuffle -- string )

        first2 dup 0 swap member? [

             >r tail* r> swap [ nth ] curry map

             CHAR: ` add* >string

        ] [ 3drop f ] if ;

    : make-shuffles ( max-out max-in -- shuffles )

        [ 1+ dup rot strings [ 2array ] with map ]

        with map concat ;

    : shuffle>quot ( shuffle -- quot )

        [

            first2 2dup [ - ] with map

            reverse [ , \ npick , \ >r , ] each

            swap , \ ndrop , length [ \ r> , ] times

        ] [ ] make ;

    : put-effect ( word -- )

        dup word-name "-" split1

        [ >array [ 1string ] map ] 2apply

        <effect> "declared-effect" set-word-prop ;

    : <shuffle ( -- ) in get ".shuffle" append set-in ;

    : shuffle> ( -- ) in get ".shuffle" ?tail drop set-in ;

    : (define-shuffles) ( names max-out quot -- )

        -rot <shuffle over length make-shuffles reverse [

            [ rot call [ create-in ] [ f ] if* ] keep

            shuffle>quot dupd over [ define put-effect ] [ 3drop ] if

        ] 2with each shuffle> ; inline

    : define-shuffles ( names max-out -- )

        [ shuffle>string ] (define-shuffles) ;

    : SHUFFLE:

        scan scan string>number define-shuffles ; parsing

    : define-tick-shuffles ( names max-out -- )

        [ tick-shuffle>string ] (define-shuffles) ;

    : TICK-SHUFFLE:

        scan scan string>number define-tick-shuffles ; parsing

     On Sun, Mar 9, 2008 at 8:17 PM, John Nowak <john@...> wrote:

    >

    > Here's a silly idea for another stack shuffling notation. The idea is

    >  that the top of the stack is always 'z', the element below is 'y', the

    >  element below that is 'x', and so on. The notation specifies the

    >  result of the shuffle, but *not* the precondition.

    >

    >  It is assumes that all variables above the lowest one used were

    >  initially on the stack. In other words, if you write '`x', it is

    >  assumed the input stack was 'xyz', so '`x' is the same as '2drop'.

    >  This causes a problem for certain words like 'nip' (which can't be

    >  expressed with one shuffle), but most work quite well.

    >

    >  Hopefully you're using monospace fonts in your email client.

    >

    >  SHUFFLE MNEMONIC TICK

    >  z-- drop `y

    >  yz-- 2drop `x

    >  xyz-- 3drop `w

    >  yz--z nip `zy `y

    >  xyz--z 2nip `zxy `x

    >  z--zz dup `zz

    >  z--zzz dup dup `zzz

    >  yz--yzyz 2dup `yzyz

    >  yz--yzyzyz 3dup `yzyzyz

    >  yz--yyz dupd `yyz

    >  yz--yzy over `yzy

    >  xyz--xyzx pick `xyzx

    >  yz--zyz tuck `zyz

    >  yz--zy swap `zy

    >  xyz--yxz swapd `yxz

    >  xyz--zyx spin `zyx

    >  xyz--yzx rot `yzx

    >  xyz--zxy -rot `zxy

    >  wxyz--xyzw roll `xyzw

    >  wxyz--zwxy -roll `zwxy

    >

    >  - John

## Daniel Ehrenberg — 2008-03-10 05:09:59

    Oops, for that code the automatic stack effect commenting only works

    for the abc-bca syntax, not the `xy syntax, which it outputs junk on.

    So just ignore the put-effect thing.

     On Sun, Mar 9, 2008 at 11:04 PM, Daniel Ehrenberg <microdan@...> wrote:

    > In Factor, this can be implemented as a simple extension to the

    >  shufflers vocab. It took a little while for me to figure out exactly

    >  how to do the translation, but I worked it out eventually. The key

    >  word there is tick-shuffle>string. Below, I pasted the modified source

    >  code. (It's not very polished.) To allow the operations you've pasted,

    >  you need to write the following line:

    >  TICK-SHUFFLE: wxyz 6

    >  To use syntax like abc-bac for swapd, you can write the following:

    >  SHUFFLE: abc 3

    >  before code that uses these shuffling operators. I'm not sure how much

    >  I like the first notation, though. You're wrong; this notation does

    >  have a single-word nip operation; it's `xz.

    >

    >  See, this is why arbitrary syntax extension like Factor has is so

    >  awesome: because you can do whatever you want. Strictly speaking, this

    >  doesn't really extend the syntax much, it just goes and defines all

    >  possible shufflers. But this is impossible in Scheme or Haskell.

    >

    >  Dan

    >  ----

    >  USING: kernel sequences words math math.functions arrays

    >  shuffle quotations parser math.parser strings namespaces

    >  splitting effects sequences.lib combinators.lib ;

    >  IN: shufflers

    >

    >  : shuffle>string ( names shuffle -- string )

    >     swap [ [ nth ] curry map ] curry map

    >     first2 "-" swap 3append >string ;

    >

    >  : tick-shuffle>string ( names shuffle -- string )

    >     first2 dup 0 swap member? [

    >         >r tail* r> swap [ nth ] curry map

    >         CHAR: ` add* >string

    >     ] [ 3drop f ] if ;

    >

    >  : make-shuffles ( max-out max-in -- shuffles )

    >     [ 1+ dup rot strings [ 2array ] with map ]

    >     with map concat ;

    >

    >  : shuffle>quot ( shuffle -- quot )

    >     [

    >         first2 2dup [ - ] with map

    >         reverse [ , \ npick , \ >r , ] each

    >         swap , \ ndrop , length [ \ r> , ] times

    >     ] [ ] make ;

    >

    >  : put-effect ( word -- )

    >     dup word-name "-" split1

    >     [ >array [ 1string ] map ] 2apply

    >     <effect> "declared-effect" set-word-prop ;

    >

    >  : <shuffle ( -- ) in get ".shuffle" append set-in ;

    >  : shuffle> ( -- ) in get ".shuffle" ?tail drop set-in ;

    >

    >  : (define-shuffles) ( names max-out quot -- )

    >     -rot <shuffle over length make-shuffles reverse [

    >         [ rot call [ create-in ] [ f ] if* ] keep

    >         shuffle>quot dupd over [ define put-effect ] [ 3drop ] if

    >     ] 2with each shuffle> ; inline

    >

    >  : define-shuffles ( names max-out -- )

    >     [ shuffle>string ] (define-shuffles) ;

    >

    >  : SHUFFLE:

    >     scan scan string>number define-shuffles ; parsing

    >

    >  : define-tick-shuffles ( names max-out -- )

    >     [ tick-shuffle>string ] (define-shuffles) ;

    >

    >  : TICK-SHUFFLE:

    >     scan scan string>number define-tick-shuffles ; parsing

    >

    >

    >

    >  On Sun, Mar 9, 2008 at 8:17 PM, John Nowak <john@...> wrote:

    >  >

    >  > Here's a silly idea for another stack shuffling notation. The idea is

    >  >  that the top of the stack is always 'z', the element below is 'y', the

    >  >  element below that is 'x', and so on. The notation specifies the

    >  >  result of the shuffle, but *not* the precondition.

    >  >

    >  >  It is assumes that all variables above the lowest one used were

    >  >  initially on the stack. In other words, if you write '`x', it is

    >  >  assumed the input stack was 'xyz', so '`x' is the same as '2drop'.

    >  >  This causes a problem for certain words like 'nip' (which can't be

    >  >  expressed with one shuffle), but most work quite well.

    >  >

    >  >  Hopefully you're using monospace fonts in your email client.

    >  >

    >  >  SHUFFLE MNEMONIC TICK

    >  >  z-- drop `y

    >  >  yz-- 2drop `x

    >  >  xyz-- 3drop `w

    >  >  yz--z nip `zy `y

    >  >  xyz--z 2nip `zxy `x

    >  >  z--zz dup `zz

    >  >  z--zzz dup dup `zzz

    >  >  yz--yzyz 2dup `yzyz

    >  >  yz--yzyzyz 3dup `yzyzyz

    >  >  yz--yyz dupd `yyz

    >  >  yz--yzy over `yzy

    >  >  xyz--xyzx pick `xyzx

    >  >  yz--zyz tuck `zyz

    >  >  yz--zy swap `zy

    >  >  xyz--yxz swapd `yxz

    >  >  xyz--zyx spin `zyx

    >  >  xyz--yzx rot `yzx

    >  >  xyz--zxy -rot `zxy

    >  >  wxyz--xyzw roll `xyzw

    >  >  wxyz--zwxy -roll `zwxy

    >  >

    >  >  - John

    >

## John Nowak — 2008-03-10 05:59:08

    On Mar 10, 2008, at 1:04 AM, Daniel Ehrenberg wrote:

     > In Factor, this can be implemented as a simple extension to the

    > shufflers vocab.

     Very nice!

    - John