[plt-scheme] polymorphism of primitive types

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Oct 18 09:22:11 EDT 2005

On Oct 18, 2005, at 8:56 AM, Yoav Goldberg wrote:

>> Let me comment however on the need to co-mingle lists and streams.
>> It is quite uncommon that the same program fragments need to process
>> both lists and streams in the same program. If you believe you have
>> a design that requires just that, please share with us.
> What I had in mind was something in the lines of:
> (define qqh (list->infinite-stream '(quarter quarter half))
> (map (lambda (pitch duration) (make-sound 'pitch: pitch 'duration: 
> duration)
>         (list DO RE MI FA SO LA SI)
>         qqh)
> but after some thinking I realized it can probably be turned into a
> stream-only implementation by wrapping map to do list->stream on all
> the list arguments.
> (I will probably also need to redefine "apply" to do a stream->list on
> it's arguments).

I believe that you don't want infinite lists but rationale ones, i.e.,
lists with repeated patterns. These are graphs and you should probably
just turn them into graphs:

(define qqh (shared ([qqh (cons quarter (cons quarter (cons half 
qqh)))]) qqh))

(map (lambda (pitch duration) ...) do-re-mi qqh)

Have you considered that?

> But, let's say I'm willing to stick to just a few selected sequence
> types, forget about ease of extensibility to more sequence types, and
> am willing to implement all the desired functions (say
> car,cdr,null?,map,append,length) for each of the types I plan to
> support, and will write my own primitive type-based dispatcher.
> I really want to stay with the traditional names, though.
> Can I have a module provide car, cdr etc without making it a new 
> language?
> (I can see how redefining some of the primitive functions can be
> considered as a new language, and otoh I can also see how it is not).

A standard trick for overloading works like this:

  (define +
    (let ([number+ +])
      (lambda (x y)
          [(and (number? x) (number? y)) (number+ x y)]
          [(and (vector? x) (vector? y)) (vector+ x y)]

You can organize this via modules very nicely and conveniently. No 
tricks truly necessary. Because:
Since you are overriding meaning of built-in primitives, you have only 
one of two possibilities:

  - use standard Scheme and be forced to re-invent square wheels like 
the above
  - use module, designated one of the modules into your desired language 
and use it.

Don't confuse using a module as a language vs making a drscheme 
The former is almost no effort; the latter requires more work.

-- Matthias

Posted on the users mailing list.