Well this is proving to be an interesting exercise
I think most would agree the new solution provides much better extensibility.
(import (rnrs))
(define (compare asc? a b)
(if asc?
(cond
[(and (number? a) (number? b)) (< a b)]
[(and (char? a) (char? b)) (char<? a b)]
[(and (string? a) (string? b)) (string<? a b)]
[else (error 'compare "not supported" a b)])
(cond
[(and (number? a) (number? b)) (> a b)]
[(and (char? a) (char? b)) (char>? a b)]
[(and (string? a) (string? b)) (string>? a b)]
[else (error 'compare "not supported" a b)])))
(define (sort asc? l a b)
(list-sort
(lambda (a* b*)
(compare asc? (a a*) (b b*)))
l))
(define-syntax from
(lambda (x)
(define (e? e o)
(eq? (syntax->datum e) (syntax->datum o)))
(syntax-case x (in select)
[(from e in l select sel)
(identifier? #'e)
(if (e? #'e #'sel)
#'l
#'(map (lambda (e) sel) l))]
[(from e in l c ... select sel)
(syntax-case #'(c ...) (where orderby asc desc)
[(where p rest ...)
(if (e? #'e #'p)
#'(from e in l
rest ...
select sel)
#'(from e in (filter (lambda (e) p) l)
rest ...
select sel))]
[(orderby p asc rest ...)
#'(from e in
(sort #t l (lambda (e) p) (lambda (e) p))
rest ...
select sel)]
[(orderby p desc rest ...)
#'(from e in
(sort #f l (lambda (e) p) (lambda (e) p))
rest ...
select sel)]
[(orderby p rest ...)
#'(from e in l
orderby p asc
rest ...
select sel)]
)])))
Posted in Default, IronScheme