Question

In Scheme, procedures like +, -, *, / works on different types of numbers, but we don't much see any other generic procedures.

For example, length works only on list so that vector-length and string-length are needed.

I guess it comes from the fact that the language doesn't really offer any mechanism for defining generic procedure (except cond of course) like "type classes" in Haskell or a standardized object system.

Is there an idiomatic scheme way to handle generic procedures that I'm not aware of ?

Was it helpful?

Solution 5

Finally, I found out a very neat solution in PLT Scheme :

(require (rename-in scheme [length list-length]))

(define length
 (λ (x)
  ((cond [(list? x) list-length]
         [(string? x) string-length]
         [(vector? x) vector-length]
         [else (error "whatever")]) x)))

(length '(a b c))
(length "abc")
(length #(1 2 3))  

OTHER TIPS

Keeping in mind that all "different types of numbers" are all scheme numbers (i.e. (number? n) equals #t) - this behavior actually makes sense. +, -, *, / and all other arithmetic operators operate on numbers only (even though in other languages they would be classified as different number types int, long, float, etc...) This is due to the fact that you can't explicitly declare number types in scheme.

If you really need a generic solution, besides using external libraries, the easiest way is to roll your own:

(define org-length length)
(define (length x)
  (cond
    ((string? x) (string-length x))
    ((vector? x) (vector-length x))
    ; keep going ...
    (else (org-length x))))

No, but you can build your own. Welcome to Scheme!

In the past I've used Swindle to provide generic functions. It's bundled with PLT Scheme. It worked well for me, but it's been a few years. There may be other alternatives out there now.

Read SICP, sections 2.4 and 2.5, which cover the implementation of procedures that can operate on generic data types by means of attaching "tags" to data objects. It's also in lecture 4-B of that MIT video series.

You really want to have an object system for that. You may want to have a look at Tiny CLOS, for instance, which is the de-facto standard object system for Chicken Scheme (see the reference manual), but seems to be available for most Scheme implementations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top