Page 1 of 1

Macros

PostPosted: Sat Oct 01, 2011 2:42 pm
by Indecipherable
Can somebody show me an example of a macro in Scheme? I coded this in Racket:

Code: Select all
(define-syntax setvar
    (syntax-rules ()
      ([setvar var value] [define var value])))


I'm trying to write this in Scheme. Can't be too different. Thanks.
Using Gambit.

Re: Macros

PostPosted: Sun Oct 02, 2011 12:09 am
by saulgoode
The same code works with Guile (substituting for the square brackets):
Code: Select all
(define-syntax setvar
  (syntax-rules ()
    ((setvar var value)
      (define var value) )))

Re: Macros

PostPosted: Fri Nov 11, 2011 1:45 pm
by Indecipherable
Doesn't work in Gambit-C. I should just stick with Racket. :D

Re: Macros

PostPosted: Sun Nov 13, 2011 2:03 am
by saulgoode
Indecipherable wrote:Doesn't work in Gambit-C.

It worked fine for me when I invoked using the command 'gsi -:s'.

A way for define-syntax/syntax-rules to match subexpr?

PostPosted: Fri Jun 29, 2012 10:44 am
by sylwester
I have a slightly advanced question about scheme macroes.

I'm wondering if syntax-rules (which is the only accepted mecro-type when setting DrRacket to R5RS) can do the trick if I want:

Code: Select all
(quote-unique sym1 sym2 sym1 sym3 "bla" sym4 "bla")
=> '(sym1 sym2 sym3 "bla" sym4)


So far I'ved tried this:
Code: Select all
(define-syntax quote-unique
  (syntax-rules (magic end)

    ;; end case
    ((quote-unique magic processed end)
     'processed)

    ;; finished iteration
    ((quote-unique magic (processed ...) sym1 end rest ... )
     (quote-unique magic (processed ... sym1) rest ... end))
   
    ;; match (doesnt work since racket doesn't like sym1 twice
    ;; but I'm looking for the same expression twice
    ((quote-unique magic processed sym1 sym1 . rest )
     (quote-unique magic processed sym1 . rest))

    ;; rotate
    ((quote-unique magic processed sym1 sym2 rest ... )
     (quote-unique magic processed sym1 rest ... sym2))

    ;; start iteration
    ((quote-unique rest ...)
     (quote-unique magic () rest ... end))))


I also saw Define syntax primer and I assume the implementation of is-eqv? would have pointed me in the right directions, but it seems it's not a macro that is defined there :(

I'm planning to add inheritance to my object system when I figured this out so any help is appreciated

Re: Macros

PostPosted: Fri Jul 06, 2012 8:44 am
by saulgoode
Code: Select all
(define (remove-duplicates lis)
  (cond
    ((null? lis)
      '() )
    ((member (car lis) (cdr lis))
      (remove-duplicates (cdr lis)) )
    (else
      (cons (car lis) (remove-duplicates (cdr lis))) )))
         
(define-syntax quote-unique
  (syntax-rules ()
    ((_ args ...)
      (remove-duplicates (quote (args ...))) )))


Perhaps?

Re: Macros

PostPosted: Sat Jul 07, 2012 6:28 am
by sylwester
Close but no cigar. Using a function works fine, but then it happens after expansion and thus runtime.
The whole point of the macro is to only do it once (compilation time) and only with static data presented in the macro.

In Common Lisp I would have done this (using your function for kicks):
Code: Select all
(defmacro quote-unique ( &rest xs )
   (list 'quote (remove-duplicates xs)))



Now, this was easy because you have CL powered macro, but I'm trying do the same with the not so easy syntax-rules and R5RS to be able to reproduce it in both gambit and chicken.. I'm actually doing the development in Racked because of the very good (but sometimes buggy) macro-stepper.

This example is actually a bare minimum problem to a more complex project I'm doing to be more familiar with syntax-rules.