[plt-scheme] Fun with paren-shape

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Jun 5 09:42:14 EDT 2007

Why don't you add | so that you can write [ n | (< 0 n 11)] ? --  
Matthias


On Jun 5, 2007, at 8:32 AM, Jens Axel Søgaard wrote:

> Hi all,
>
> Here's a fun little hack. It provides concise
> syntax for integer ranges and vector references.
>
>  [a .. b]  => (interval a b)
>  (... expr1 [expr2] ...) => (... (vector-ref expr1 expr2) ...)
>
>
> Example:
>
> > (require index)
>
> > (define (sum xs) (apply + xs))
>
> > [1 .. 11]
> (1 2 3 4 5 6 7 8 9 10)
>
> > (sum [1 .. 11])
> 55
>
>
> > (define v (vector 'a 'b 'c))
> > (list v[0] v[1] v[2])
> (a b c)
>
> > (+ (vector 1 2)[0] 3)
> 4
>
>
> > (define (len o)
>     (cond
>       [(pair? o)   (length o)]
>       [(vector? o) (vector-length o)]
>       [(string? o) (string-length o)]
>       [(bytes? o)  (bytes-length o)]
>       [else        (error 'len "I give up" o)]))
>
> > (define v1 (vector 1 0 1))
> > (define v2 (vector 2 3 4))
>
> > (define (dot-product v1 v2)
>     (sum (map (λ (i) (* v1[i] v2[i]))
>               [0 .. (len v1)])))
> 6
>
>
> (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 (..) module-or-top-identifier=?
>       [(_ a .. b)
>        (bracket-shaped? stx)
>        (quasisyntax/loc stx
>          (interval a b))]
>       [(_ 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))])))
>
> (require index)
>
> (define (sum xs)
>   (apply + xs))
>
> [1 .. 11]
> (sum [1 .. 11])
>
>
> (define v (vector 'a 'b 'c))
> (list v[0] v[1] v[2])
>
> (define (len o)
>   (cond
>     [(pair? o)   (length o)]
>     [(vector? o) (vector-length o)]
>     [(string? o) (string-length o)]
>     [(bytes? o)  (bytes-length o)]
>     [else        (error 'len "I give up" o)]))
>
> (define v1 (vector 1 0 1))
> (define v2 (vector 2 3 4))
>
> (define (dot-product v1 v2)
>   (sum (map (λ (i) (* v1[i] v2[i]))
>             [0 .. (len v1)])))
>
>
>
> -- 
> Jens Axel Søgaard
>
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.