[plt-scheme] Fun with paren-shape
Did you consider using utf-8? You can write something like this:
[ n ∈ nat : (< n 10) ]
where "nat" and maybe a few other things are builtins or from some
extensible generator set. Indeed, you could probably use the usual
natural number sign.
Also, I think you should use {} instead of []. Not only is it more
traditional, but {} is rarely used (at least in my code :).
BTW, this seems much more robust than the vector notation (which,
iiuc, won't work at the top-level, or in the test of an if, etc)
Robby
On 6/5/07, Jens Axel Søgaard <jensaxel at soegaard.net> wrote:
>
> > [(+ n 3) : n is (< n 10) (even? n)]
> (3 5 7 9 11)
>
> > [(+ n 3) : n is (< n 10)]
> (3 4 5 6 7 8 9 10 11 12)
>
> > [(* n n) : n is (< n 10) (odd? n)]
> (1 9 25 49 81)
>
> Is there a better keyword than "is"?
>
> /Jens Axel
>
>
> (module index mzscheme
> (provide (rename my-app #%app))
> (require-for-syntax (lib "stx.ss" "syntax"))
>
> (define (interval n m)
> (cond
> [(>= n m) '()]
> [(< n m) (cons n (interval (+ n 1) m))]))
>
> (define-syntax (my-app stx)
> (define (bracket-shaped? stx)
> (equal? (syntax-property stx 'paren-shape) #\[))
> (define (brackets? parens)
> (syntax-case parens ()
> [(x) (bracket-shaped? parens)]
> [_ #f]))
> (define (range? stx)
> (syntax-case* stx (..) module-or-top-identifier=?
> [(a .. b) (bracket-shaped? stx)]
> [_ #f]))
> (define (handle-brackets exprs)
> ; vector brackets
> (let loop ([exprs exprs]
> [prev-exprs '()])
> (cond
> [(null? exprs)
> (reverse prev-exprs)]
> [(null? (cdr exprs))
> (loop (cdr exprs) (cons (car exprs) prev-exprs))]
> [(not (brackets? (cadr exprs)))
> (loop (cdr exprs) (cons (car exprs) prev-exprs))]
> [else
> (loop (cddr exprs)
> (cons (quasisyntax/loc (cadr exprs)
> (vector-ref #,(car exprs) #,@(cadr exprs)))
> prev-exprs))])))
> (define (handle-ranges exprs)
> (let loop ([exprs exprs]
> [prev-exprs '()])
> (cond
> [(null? exprs)
> (reverse prev-exprs)]
> [(not (range? (car exprs)))
> (loop (cdr exprs) (cons (car exprs) prev-exprs))]
> [else
> (with-syntax ([[from .. to] (car exprs)])
> (loop (cdr exprs)
> (cons (syntax/loc (car exprs)
> (interval from to))
> prev-exprs)))])))
> (syntax-case* stx (.. : is) module-or-top-identifier=?
> [(_ a .. b)
> (bracket-shaped? stx)
> (quasisyntax/loc stx
> (interval a b))]
> [(_ expr : n is while-pred-expr)
> (bracket-shaped? stx)
> (quasisyntax/loc stx
> (let loop ([n 0])
> (if while-pred-expr
> (cons expr (loop (+ n 1)))
> '())))]
> [(_ expr : n is while-pred-expr filter-expr)
> (bracket-shaped? stx)
> (quasisyntax/loc stx
> (let loop ([n 0])
> (if while-pred-expr
> (if filter-expr
> (cons expr (loop (+ n 1)))
> (loop (+ n 1)))
> '())))]
> [(_ n : while-pred-expr)
> (bracket-shaped? stx)
> (quasisyntax/loc stx
> (let loop ([n 0])
> (if while-pred-expr
> (cons n (loop (+ n 1)))
> '())))]
> [(_ n : while-pred-expr filter-expr)
> (bracket-shaped? stx)
> (quasisyntax/loc stx
> (let loop ([n 0])
> (if while-pred-expr
> (if filter-expr
> (cons n (loop (+ n 1)))
> (loop (+ n 1)))
> '())))]
> [(_ expr . more )
> (or (ormap brackets? (cddr (syntax->list stx)))
> (ormap range? (cdr (syntax->list stx))))
> (with-syntax ([(expr ...)
> (handle-ranges
> (handle-brackets
> (cdr (syntax->list stx))))])
> (quasisyntax/loc stx
> (#%app expr ...)))]
> [(_ . more)
> (syntax/loc stx
> (#%app . more))])))
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>