From: howard yeh
Subject: custom lexical information with macro?
Date: 
Message-ID: <1181759837.247585.35380@z28g2000prd.googlegroups.com>
Hi,

I am _trying_ to grok syntax-case. Getting pretty desperate. Anyway,
as an exercise, I thought I'd make an extensible piping construct. The
idea is that if a symbol in a list is marked as a pipe, then all
positions in the list before that symbol become the tail of the piping
expression.

Suppose i marked "if", and "print" as pipes.

(pipe-app list 1 2 if (test))
;;==
(if test (list 1 2))

(pipe-app foo a b c if (test1) if (test2) print)
;;==
(print (if (test2) (if (test1) (foo a b c))))

So it's a simple-minded transform that doesn't need to know about the
meaning of the symbols marked as pipes. But the piping symbols should
prevent capturing:

(let ((if 1)
      (print 2))
  (pipe-app list 1 if 2 print))
;;==
(let ((if 1)
      (print 2))
  (list 1 if 2 print))


My implementation works up to this point, but I don't know what to do
if I want local pipes. Something like:

(let ((if print))
  (let-pipe (if)
   (pipe-app list a b c if)))
;;==
(print (list a b c))

There should be a trick, but I don't see it.

(Another side question. In a botched effort to introduce local pipes,
I used "expand" in the transformer. What does that do? Does it do
expansion in the transforming environment of the transforming
environment (therefore the syntax object produced is useless in run-
time)?

Anyway, I got the error "identifier out of context", which is the one
that I get if the output of the transformer has an identifier that
refers to a binding in the transformer environment.

(define-syntax (foo x)
  (syntax-case x ()
    ((_ e) (expand (syntax e)))))

Apparently works. What is it doing?
)


I am using plt-scheme.

Howard
-----------------------------------------------------
(define-syntax pipe-app
  (lambda (x)
    (syntax-case x ()
      ((_ e ...)
       (not (null? (syntax->list (syntax (e ...)))))
       (let loop ((exps (reverse (syntax->list (syntax (e ...)))))
                  (acc ()))
         (if (null? exps)
             #`#,acc
             (if (and (is-pipe? (car exps))
                      (not (null? (cdr exps))))
		 ;; not tail-recursive. Can use continuation
		 ;; passing style instead.
                 (let ((result (loop (cdr exps) ())))
                   #`(#,(car exps) #,@acc #,result))
                 (loop (cdr exps) (cons (car exps) acc))))))
      )))

(begin-for-syntax
 (define pipes ())
 (define (active-pipes) pipes)
 (define (define-pipe-symbol identifier)
   (set! pipes (cons identifier pipes)))
 (define (is-pipe? identifier)
   (and (identifier? identifier)
        (let loop ((pipes pipes))
          (and (not (null? pipes))
               (if (free-identifier=? (car pipes) identifier)
                   #t
                   (loop (cdr pipes)))))))
 (define-pipe-symbol (syntax if))
 (define-pipe-symbol (syntax print))

 )
From: howard yeh
Subject: Re: custom lexical information with macro?
Date: 
Message-ID: <1181759901.388652.165610@g37g2000prf.googlegroups.com>
Ooops. Should've posted to comp.lang.scheme.

I am soooo sorry :(

On Jun 13, 11:37 am, howard yeh <······@gmail.com> wrote:
> Hi,
>
> I am _trying_ to grok syntax-case. Getting pretty desperate. Anyway,
> as an exercise, I thought I'd make an extensible piping construct. The
> idea is that if a symbol in a list is marked as a pipe, then all
> positions in the list before that symbol become the tail of the piping
> expression.
>
> Suppose i marked "if", and "print" as pipes.
>
> (pipe-app list 1 2 if (test))
> ;;==
> (if test (list 1 2))
>
> (pipe-app foo a b c if (test1) if (test2) print)
> ;;==
> (print (if (test2) (if (test1) (foo a b c))))
>
> So it's a simple-minded transform that doesn't need to know about the
> meaning of the symbols marked as pipes. But the piping symbols should
> prevent capturing:
>
> (let ((if 1)
>       (print 2))
>   (pipe-app list 1 if 2 print))
> ;;==
> (let ((if 1)
>       (print 2))
>   (list 1 if 2 print))
>
> My implementation works up to this point, but I don't know what to do
> if I want local pipes. Something like:
>
> (let ((if print))
>   (let-pipe (if)
>    (pipe-app list a b c if)))
> ;;==
> (print (list a b c))
>
> There should be a trick, but I don't see it.
>
> (Another side question. In a botched effort to introduce local pipes,
> I used "expand" in the transformer. What does that do? Does it do
> expansion in the transforming environment of the transforming
> environment (therefore the syntax object produced is useless in run-
> time)?
>
> Anyway, I got the error "identifier out of context", which is the one
> that I get if the output of the transformer has an identifier that
> refers to a binding in the transformer environment.
>
> (define-syntax (foo x)
>   (syntax-case x ()
>     ((_ e) (expand (syntax e)))))
>
> Apparently works. What is it doing?
> )
>
> I am using plt-scheme.
>
> Howard
> -----------------------------------------------------
> (define-syntax pipe-app
>   (lambda (x)
>     (syntax-case x ()
>       ((_ e ...)
>        (not (null? (syntax->list (syntax (e ...)))))
>        (let loop ((exps (reverse (syntax->list (syntax (e ...)))))
>                   (acc ()))
>          (if (null? exps)
>              #`#,acc
>              (if (and (is-pipe? (car exps))
>                       (not (null? (cdr exps))))
>                  ;; not tail-recursive. Can use continuation
>                  ;; passing style instead.
>                  (let ((result (loop (cdr exps) ())))
>                    #`(#,(car exps) #,@acc #,result))
>                  (loop (cdr exps) (cons (car exps) acc))))))
>       )))
>
> (begin-for-syntax
>  (define pipes ())
>  (define (active-pipes) pipes)
>  (define (define-pipe-symbol identifier)
>    (set! pipes (cons identifier pipes)))
>  (define (is-pipe? identifier)
>    (and (identifier? identifier)
>         (let loop ((pipes pipes))
>           (and (not (null? pipes))
>                (if (free-identifier=? (car pipes) identifier)
>                    #t
>                    (loop (cdr pipes)))))))
>  (define-pipe-symbol (syntax if))
>  (define-pipe-symbol (syntax print))
>
>  )