# Dynamic dispatch in a concatenative language?

## Slava Pestov — 2004-04-16 15:32:01

    Hi all,

    What do people think about this?

    For example right now I have a word 'prettyprint' that formats a given

    expression and produces hyperlinks (if the output stream supports it);

    it uses the 'switch on type' design pattern:

    : prettyprint* ( indent obj -- indent )

        [

            [ not       ] [ prettyprint-object ]

            [ list?     ] [ $[ $] prettyprint-list ]

            [ compound? ] [ worddef>list $: $; prettyprint-list ]

            [ compiled? ] [ worddef>list $: $; prettyprint-list ]

            [ shuffle?  ] [ worddef>list $~<< $>>~ prettyprint-list ]

            [ drop t    ] [ prettyprint-object ]

        ] cond ;

    However this is not in line with the principles of modular design; its

    not extensible, etc. Indeed if it was just this case that was

    problematic it would be not be a big deal, but this kind of thing

    appears all time; in a slightly different form in the arithmetic words

    for example, to handle all the different numerical types. Also the I/O

    words suffer from the same problem.

    Indeed, I'm thinking of adding a facility to the language where

    something like this is possible:

    : prettyprint* ( indent obj:<<cons>> -- indent )

        $[ $] prettyprint-list ;

    : prettyprint* ( indent obj:<<compound>> -- indent )

        $: $; prettyprint-list ;

    : prettyprint* ( indent obj:<<ANY>> -- indent )

        prettyprint-object ;

    : + ( x:<<fixnum>> y:<<fixnum>> -- z )

        add two integers ;

    : + ( x:<<bignum>> y:<<bignum>> -- z )

        all two big integers ;

    etc.

    The syntax is just an idea; I'll probably settle for something different

    if I chose to implement this, but the concept should be clear; it is of

    course actually parsing the ( ... ) comment, and using :<<...>> as a

    type specifier.

    Then when code calls 'prettyprint*', the appropriate form is chosen at

    runtime based on the top of the stack.

    This could be combined with a stronger stack effect checker to check

    types (but I don't want it to *fail* compilation of types cannot be

    inferred).

    --

    Slava Pestov

## andrew cooke — 2004-04-16 15:45:55

    your last soln is what i'm aiming for.  you can define the same function

    with different patterns, and patterns can contain type info.  first match

    is executed.  compiler should eventually warn for incomplete defintions.

    see haskell syntax (just the same).

    cheers,

    andrew

    Slava Pestov said:

     > Hi all,

    >

    > What do people think about this?

    >

    > For example right now I have a word 'prettyprint' that formats a given

    > expression and produces hyperlinks (if the output stream supports it);

    > it uses the 'switch on type' design pattern:

    >

    > : prettyprint* ( indent obj -- indent )

    >     [

    >         [ not       ] [ prettyprint-object ]

    >         [ list?     ] [ $[ $] prettyprint-list ]

    >         [ compound? ] [ worddef>list $: $; prettyprint-list ]

    >         [ compiled? ] [ worddef>list $: $; prettyprint-list ]

    >         [ shuffle?  ] [ worddef>list $~<< $>>~ prettyprint-list ]

    >         [ drop t    ] [ prettyprint-object ]

    >     ] cond ;

    >

    > However this is not in line with the principles of modular design; its

    > not extensible, etc. Indeed if it was just this case that was

    > problematic it would be not be a big deal, but this kind of thing

    > appears all time; in a slightly different form in the arithmetic words

    > for example, to handle all the different numerical types. Also the I/O

    > words suffer from the same problem.

    >

    > Indeed, I'm thinking of adding a facility to the language where

    > something like this is possible:

    >

    > : prettyprint* ( indent obj:<<cons>> -- indent )

    >     $[ $] prettyprint-list ;

    >

    > : prettyprint* ( indent obj:<<compound>> -- indent )

    >     $: $; prettyprint-list ;

    >

    > : prettyprint* ( indent obj:<<ANY>> -- indent )

    >     prettyprint-object ;

    >

    > : + ( x:<<fixnum>> y:<<fixnum>> -- z )

    >     add two integers ;

    >

    > : + ( x:<<bignum>> y:<<bignum>> -- z )

    >     all two big integers ;

    >

    > etc.

    >

    > The syntax is just an idea; I'll probably settle for something different

    > if I chose to implement this, but the concept should be clear; it is of

    > course actually parsing the ( ... ) comment, and using :<<...>> as a

    > type specifier.

    >

    > Then when code calls 'prettyprint*', the appropriate form is chosen at

    > runtime based on the top of the stack.

    >

    > This could be combined with a stronger stack effect checker to check

    > types (but I don't want it to *fail* compilation of types cannot be

    > inferred).

    > --

    > Slava Pestov

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

     --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito