Greetings, list. I don't know whether this is the right list or not, but I
could not find a better place.
Scheme language lacks such features as pattern matching (if we don't speak of
syntax definitions) or list comprehensions. As far as I could see occasionally
such notions arise in talks, and implementations happen, but they are not in
SRFI list or something.
I have made a library that contains R5RS-compliant syntax definitions for
pattern-matching forms (lets, cases, lambdas) and for-syntax. This probably can
be regarded as a proposition. As a syntax, they are definitely slower that they
would be, were they a compiler magic.
The library is called prelude.scm.
This is an example of pattern-matching syntax — a procedure that computes the
length of (improper) lists, vectors and strings, and returns 0 for any other
type of argument:
(define generic-length
(<-case-lambda
(((v) ? (vector? v)) (vector-length v)) ; vector
(((s @ (string _ . _))) (string-length s)) ; string
(((_ . l)) (letrec ; list or improper list
((len (<-case-lambda
((accum (_ . l)) (len (+ 1 accum) l))
((accum _) accum))))
(+ 1 (len 0 l))))
((_) 0) ; any other object
(_ (error "(generic-length): one argument expected")) ; zero, or more
than 1, arguments
))
(generic-length '(1 2 3)) ===> 3
(generic-length '#(4 5 6)) ===> 3
(generic-length "Hello!") ===> 6
(generic-length 42) ===> 0
The same definition in pseudo-Haskell would be:
genericLength v | isVector v = vectorLength v
genericLength s@(String _:_) = stringLength s
genericLength (_:l) = 1 + genericLength l
genericLength _ = 0
genericLength ... = error "genericLength: one argument expected"
List comprehension exists in the form of (for) and (do-for) syntaxes:
(for ((x '(1 2 3)) ((string y . _) <- '("Hello" "world!"))) (show x #\: y))
===> ("1:H" "1:w" "2:H" "2:w" "3:H" "3:w")
Some procedures analogous to those of Haskell's Prelude are also defined, but
they are more Schematic: (values)-aware and explicitly tail-recursive where
possible. For example, (filter proc list1 list2...) acts like Haskell's filter,
but returns several list values when there are more than one list arguments
(proc should accept as many arguments and is applied to all the lists
elementwise); and ($*) is a functional composition combinator, defined as this:
($*) ===> values
($* proc) ===> proc
($* proc1 proc2 proc3 ... proc_n) ===> the composition of proc1, ..., by the
following rules:
every proc_i should accept as many arguments as proc_i+1 returns values;
when the composition is called with a set of arguments, first proc_n is called
with those arguments, then the composition of proc1, ..., proc_n-1 is called
with values, returned by proc_n, as arguments via a tail call.
And, among others, procedures for a simpler I/O: (println), (show), etc.
I don't know whether this library has anything to do with the future of Scheme,
but I thought it was worth being developed.
You can download it at https://sourceforge.net/projects/preludescm/
Cheers,
Denis Trapeznikov.
_______________________________________________
Scheme-reports mailing list
[email protected]
http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports