[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

taking off a parenthesis

This page is part of the web mail archives of SRFI 71 from before July 7th, 2015. The new archives for SRFI 71 contain all messages, not just those from before July 7th, 2015.



Let me introduce a funny idea.

If the outer-most parenthesis of the let-formal is taken off, We can use
the
lambda-formal without additional key-words and parenthesis complexity.
However, it is swindling by a clever trick, because the taken-off
parenthesis
should be inserted later.  Of course, it becomes incompatible with
r5rs-let*.

Rough spec: (bare-let* (a1 a2 ...) ... () body1 body2 ...)

(bare-let* ((a 10) (b 20))
	   ((c d e) (values 30 40 50))
	   ((f . g) (apply values '(60 70 80 90)))
	   (h 100)
	   ()			; a parenthesis taken off
	   (list a b c d e f g h))
=> (10 20 30 40 50 60 (70 80 90) (100))

(define-syntax bare-let*
  (syntax-rules ()
    ((bare-let* () clause ...)
     ((lambda () clause ...)))
    ((bare-let* ((name val) ...) clause ...)
     (let* ((name val) ...)
	(bare-let* clause ...)))
    ((bare-let* (formal vals) clause ...)
     (call-with-values (lambda () vals)
       (lambda formal
	 (bare-let* clause ...))))))

	 
It can be extended as followings.

(bare-let* (_ (a 10) (b 20))		; let
	   (* (c 30) (d 40))		; let*
	   (% (e (lambda () 1)))	; letrec
	   (& (f 50) (g 60))		; and-let
	   (&* (h 70) (i 80) (j 90))	; and-let*
	   (lp (k 100) (l 200))		; named let
	   (loop (m n . o) (apply values '(300 400))) ; named let
	   (() (display (list k l m n o)) (newline)) ; begin
	   (~ '(500 600) (p 1 (number? p)) (q 2)) ; let-optional
	   (~* '(700 800 900) (r 3) (s 4) t) ;let-optional*
	   ()
	   (display "examxple:")
	   (if (< m 500)
	       (loop 555 666 777 888)
	       (list a b c d e f g h i j k l m n o p q r s t)))

=>
(100 200 300 400 ())
examxple:(100 200 555 666 (777 888))
examxple:(10 20 30 40 #<procedure:e> 50 60 70 80 90 100 200 555 666 (777
888) 500 600 700 800 (900))

(define-syntax bare-let*
  (syntax-rules (~ ~* ! !* % & &* * _) ; @ # $ ^ + |
    ((bare-let* () clause ...)
     ((lambda () clause ...)))
    ((bare-let* ((name val) ...) clause ...)
     ((lambda (name ...)
	(bare-let* clause ...))
      val ...))
    ((bare-let* (_ (name val) ...) clause ...)
     (let ((name val) ...)
       (bare-let* clause ...)))
    ((bare-let* (* (name val) ...) clause ...)
     (let* ((name val) ...)
       (bare-let* clause ...)))
    ((bare-let* (% (name val) ...) clause ...)
     (letrec ((name val) ...)
       (bare-let* clause ...)))
    ((bare-let* (& (name val) ...) clause ...)
     (and-let ((name val) ...)
       (bare-let* clause ...)))
    ((bare-let* (&* (name val) ...) clause ...)
     (and-let* ((name val) ...)
       (bare-let* clause ...)))
    ;; The order of followings are important.
    ((bare-let* (~ rest p1 p2 ...) clause ...)
     (let-opt rest (p1 p2 ...)
	      (bare-let* clause ...)))
    ((bare-let* (~* rest p1 p2 ...) clause ...)
     (let-opt* rest (p1 p2 ...)
	       (bare-let* clause ...)))
    ((bare-let* (! rest p1 p2 ...) clause ...)
     (let-cat rest (p1 p2 ...)
	      (bare-let* clause ...)))
    ((bare-let* (!* rest p1 p2 ...) clause ...)
     (let-cat* rest (p1 p2 ...)
	       (bare-let* clause ...)))
    ((bare-let* (() expression ...) clause ...)
     ((lambda ()
	expression ... (bare-let* clause ...))))
    ((bare-let* (loop (name val) ...) clause ...)
     ((letrec ((loop (lambda (name ...)
		       (bare-let* clause ...))))
	loop)
      val ...))
    ((bare-let* (loop formal vals) clause ...)
     (letrec ((loop (lambda formal
		      (bare-let* clause ...))))
       (call-with-values (lambda () vals)
	 loop)))
    ((bare-let* (formal vals) clause ...)
     (call-with-values (lambda () vals)
       (lambda formal
	 (bare-let* clause ...))))))

(define-syntax and-let
  (syntax-rules ()
    ((and-let ((name val) ...) body1 body2 ...)
     (and val ...
	  ((lambda (name ...) body1 body2 ...)
	   val ...)))
    ;; ((and-let tag ((name val) ...) body1 body2 ...)
    ;;  (and val ...
    ;; 	  ((letrec ((tag (lambda (name ...) body1 body2 ...)))
    ;; 	    tag)
    ;; 	   val ...)))
    ))

(define-syntax and-let*
  (syntax-rules ()
    ((and-let* () body1 body2 ...)
     ((lambda () body1 body2 ...)))
    ((and-let* ((name1 val1) (name2 val2) ...) body1 body2 ...)
     ;;(and-let ((name1 val1))
     ;; 	(and-let* ((name2 val2) ...) body1 body2 ...)))))
     (and val1
	  ((lambda (name1) (and-let* ((name2 val2) ...) body1 body2
...))
	   val1)))))

--
Joo ChurlSoo