From: funkyj
Subject: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138301751.797992.109590@g14g2000cwa.googlegroups.com>
I've heard that CL macros are more poweful than Scheme macros.
Assuming this is true, what is the simplest example illustrating this
difference?

another CL vs Scheme question:

What is the history behind CL having separate function and variable
namespaces?

It seems to me that CL's 2 namespaces confers no particular advantage
while adding complexity.  Is the CL 2 namespace approach merely an
evolutionary artifact or does it confer some significant advantage over
the 1 namespace approach that I have yet to perceive?

Please direct all religious follow up discussions to alt.flame

Regards,
  --jfc

From: Kaz Kylheku
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138312218.572468.169090@g47g2000cwa.googlegroups.com>
funkyj wrote:
> I've heard that CL macros are more poweful than Scheme macros.

What, in the Turing sense?

> Assuming this is true, what is the simplest example illustrating this
> difference?

Assuming it's true, is it relevant?

Suppose that some A is more powerful than some B, but for the task you
want to do, its expressiveness isn't up to snuff?

Power is irrelevant a lot of the time.

You can design some completely unuseable Turing-complete language, as a
joke, and it will be more powerful than some lame but practical
programming language in which only loops with fixed bounds can be
written, and in which there is no recursion. But it will still be
easier to get work done in the latter one.

Schemers who like their macros don't care that pure source code macros
might be more powerful. They like how those macros express what they
do.

> another CL vs Scheme question:
>
> What is the history behind CL having separate function and variable
> namespaces?
>
> It seems to me that CL's 2 namespaces confers no particular advantage
> while adding complexity.

You can add local functions to code without worrying that the bindings
will shadow a variable reference, only that they might shadow a
function reference.

You can use LIST as a variable name instead of LST.

But there are deeper issues.

> Is the CL 2 namespace approach merely an
> evolutionary artifact or does it confer some significant advantage over
> the 1 namespace approach that I have yet to perceive?

A real-life symbol, as opposed to a programming language symbol, is a
trigger for many meanings, some of which are unrelated.

CL has much more than just two namespaces for a symbol.

Would it be right to have exactly one binding, one property in a
symbol, in any given lexical or dynamic context, and make that binding
do all the work?

How far should the obsession with one namespace be taken? If you have
code like

(block foo ...)

and within that block you define a variable called FOO, should that
shadow the block name, so that (GO FOO) no longer works?

Should you have only static scope, because dynamic scope is introduces
another symbol namespace?

Should restarts and catch tags shadow each other too?

Should I not be able to define a class FOO and a function FOO at the
same time?

What about property lists; they let you create your own symbol
namespaces.

Thus, given all these namespaces, why should two of them, namely object
and function bindings, be merged together? Because functions are
objects? Is that a good enough reason?

Catch tags and restarts are both dynamic places to which a non-local
control transfer can take place, yet they are independent.

 > Please direct all religious follow up discussions to alt.flame

I.e. where your original article belongs?
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138404553.308622.301490@g47g2000cwa.googlegroups.com>
Kaz Kylheku wrote:
> funkyj wrote:
>  > Please direct all religious follow up discussions to alt.flame
>
> I.e. where your original article belongs?

As for power, I think several others have already acknowledged that
R5RS macros are not as expressive as CL macros (that was my original
question).  I have also learned an interesting fact: that the de facto
scheme macro system 'syntax-case' is more or less on par with CL
macros.

I think your various rhetorical questions touch on many of the points
covered in the Gabriel & Pitman paper
(http://www.nhplace.com/kent/Papers/Technical-Issues.html mentioned by
Pascal Costanza), albeit in a more vituperative and less illuminating
way.

I think it is safe to say that if experienced lispers like the EuLisp
group mentioned in the G&P paper thought that lisp-1 is better than
lisp-2 and G&P felt the question is topic worthy of writing and
publishing a paper on then it isn't too unreasonable that a newbie
might ask the similar questions.

Regards,
  --jfc

P.S. perhaps you should add more fibre to you diet, it helps with
digestion.
From: Kaz Kylheku
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138416672.102773.219120@g14g2000cwa.googlegroups.com>
funkyj wrote:
> I think your various rhetorical questions touch on many of the points
> covered in the Gabriel & Pitman paper
> (http://www.nhplace.com/kent/Papers/Technical-Issues.html mentioned by
> Pascal Costanza), albeit in a more vituperative and less illuminating
> way.

Pardon me! Next time I type a Usenet article, I will follow your
scholarly example and polish it to the brilliance and information
content of a Kent Pitman paper.

> P.S. perhaps you should add more fibre to you diet, it helps with
> digestion.

What, am I not consuming insoluble roughage by dealing wth the likes of
you here?
From: Alexander Schmolck
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <yfswtglb4hp.fsf@oc.ex.ac.uk>
"funkyj" <······@gmail.com> writes:

> Kaz Kylheku wrote:
> > funkyj wrote:
> >  > Please direct all religious follow up discussions to alt.flame
> >
> > I.e. where your original article belongs?
[...]
> I think your various rhetorical questions touch on many of the points
> covered in the Gabriel & Pitman paper
> (http://www.nhplace.com/kent/Papers/Technical-Issues.html mentioned by
> Pascal Costanza), albeit in a more vituperative and less illuminating
> way.

> I think it is safe to say that if experienced lispers like the EuLisp
> group mentioned in the G&P paper thought that lisp-1 is better than
> lisp-2 and G&P felt the question is topic worthy of writing and
> publishing a paper on then it isn't too unreasonable that a newbie
> might ask the similar questions.

Two observations:

1. this:

>> It seems to me that CL's 2 namespaces confers no particular advantage
>> while adding complexity.  Is the CL 2 namespace approach merely an
>> evolutionary artifact or does it confer some significant advantage over
>> the 1 namespace approach that I have yet to perceive?

   Is not necessarily the best way to ask such a question, if you don't want
   to come across as trolling (this is a topic on which there have been
   countless discussions -- and on which there are divided opinions, hence
   scheme. So to come to comp.lang.lisp as the umpteenth person to ask,
   apparently without having bothered to google "lisp-1" vs "lisp-2",
   something along the lines of "are 2 namespaces really as stupid as I happen
   to think as a completely newbie" is not the best way to set about things).

> P.S. perhaps you should add more fibre to you diet, it helps with
> digestion.

2. Kaz's message was quite informative -- if you additionally expect to be
   treated with exquisite politeness you would stand a better chance of not
   being disappointed if you observed netiquette like trying to google the web
   and the newsgroup for past discussions on the topic before you post (and if
   you have done that, there is no harm in writing something like "even after
   reading Kent Pitman's discussion on FOO it still isn't clear to me why
   ...")

'as
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43dabc25$0$38699$edfadb0f@dread12.news.tele.dk>
funkyj wrote:
> Kaz Kylheku wrote:
> 
>>funkyj wrote:
>> > Please direct all religious follow up discussions to alt.flame
>>
>>I.e. where your original article belongs?

> I have also learned an interesting fact: that the de facto
> scheme macro system 'syntax-case' is more or less on par with CL
> macros.

That's the kind of statements that will get you flamed - Kaz
were right in warning you ;-)


-- 
Jens Axel S�gaard
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138435399.569776.86990@g49g2000cwa.googlegroups.com>
Jens Axel Søgaard wrote:
> funkyj wrote:
> > Kaz Kylheku wrote:
> >
> >>funkyj wrote:
> >> > Please direct all religious follow up discussions to alt.flame
> >>
> >>I.e. where your original article belongs?
>
> > I have also learned an interesting fact: that the de facto
> > scheme macro system 'syntax-case' is more or less on par with CL
> > macros.
>
> That's the kind of statements that will get you flamed

Either you are pulling my leg in which case I commend you on your
deadpan humor or folks have senstivities far beyond my comprehension.

I won't bother asking what exactly is inflammatory about my statement
above.  I suspect it is one of those "if you have to ask, you'll never
know" kind of things..

Regards,
  --jfc
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43db43a1$0$38618$edfadb0f@dread12.news.tele.dk>
funkyj wrote:
> Jens Axel S�gaard wrote:
funkyj wrote:
>>>I have also learned an interesting fact: that the de facto
>>>scheme macro system 'syntax-case' is more or less on par with CL
>>>macros.
>>
>>That's the kind of statements that will get you flamed
> 
> Either you are pulling my leg in which case I commend you on your
> deadpan humor or folks have senstivities far beyond my comprehension.

It's the "more or less". The 'syntax-case' and the CL
macro system are equally powerful.

-- 
Jens Axel S�gaard
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <4416pgF1p95udU1@individual.net>
Jens Axel S�gaard wrote:

> It's the "more or less". The 'syntax-case' and the CL
> macro system are equally powerful.

Strictly speaking, syntax-case macros are more powerful than CL macros. 
Wrt accidental/intentional variable capture, they are both on par. Wrt. 
referential transparency, Common Lisp is less expressive.

Here is an example using syntax-rules (which is sufficient because 
syntax-rules supports referential transparency):

(let ((foo (lambda () (display "version 1"))))
   (let-syntax ((bar (syntax-rules () ((bar) (foo))))
     (let ((foo (lambda () (display "version 2"))))
       (bar))))

This prints "version 1" - that is, the macro expansion for bar refers to 
the original definition of foo, not to the one that is locally 
introduced. With syntax-case you can also decide to refer to the local 
redefinition.

In Common Lisp, macros are by default not referentially transparent:

(flet ((foo () (print "version 1")))
   (macrolet ((bar () '(foo)))
     (flet ((foo () (print "version 2")))
       (bar))))

This prints "version 2", that is, the local redefinition is called.

In order to avoid this, one has to capture the original definition in a 
uniquely named function:

(flet ((foo () (print "version 1")))
   (flet ((.foo. () (foo)))
     (macrolet ((bar () '(.foo.)))
       (flet ((foo () (print "version 2")))
         (bar)))))

This prints "version 1". (You wouldn't program it like this, but the 
idea here is that the (flet ((.foo. ...)) (macrolet ...)) combination 
could be the result of another macro, with .foo. being a generated 
symbol instead).

You can achieve something similar for variables:

(let ((foo "version 1"))
   (flet ((.foo. () foo)
          ((setf .foo.) (value) (setf foo value)))
     (symbol-macrolet ((bar (.foo.)))
       (let ((foo "version 2"))
         (print bar)))))

Achieving referential transparency for catch tags is probably also 
straightforward. However, I don't have a good idea how to achieve it for 
block names and go tags - this seems to be impossible without locally 
redefining return-from or go respectively, and that is prohibited by 
ANSI Common Lisp. So in this sense, syntax-case is strictly more 
expressive (given that block names and go tags are implemented in Scheme 
by way of call/cc and stored in variables as well).

Of course, it's a different question whether this really matters... ;)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43db6f06$0$38678$edfadb0f@dread12.news.tele.dk>
Pascal Costanza wrote:
> Jens Axel S�gaard wrote:
> 
>> It's the "more or less". The 'syntax-case' and the CL
>> macro system are equally powerful.
> 
> Strictly speaking, syntax-case macros are more powerful than CL macros. 
> Wrt accidental/intentional variable capture, they are both on par. Wrt. 
> referential transparency, Common Lisp is less expressive.

I could have sworn you found a solution the last time we discussed this.

<http://groups.google.com/group/comp.lang.lisp/msg/4d905c8db6739216?hl=en&>

 > A chieving referential transparency for catch tags is probably also
 > straightforward. However, I don't have a good idea how to achieve it
 > for block names and go tags - this seems to be impossible without
 > locally redefining return-from or go respectively, and that is
 > prohibited by ANSI Common Lisp. So in this sense, syntax-case is
 > strictly more expressive (given that block names and go tags are
 > implemented in Scheme by way of call/cc and stored in variables as
 > well).

My CommonLisp skills isn't sufficient to understand the finer details of
your macros, but I get the point: referential transparency is harder to
achieve than hygiene.

 > Of course, it's a different question whether this really matters... ;)

Yep.

-- 
Jens Axel S�gaard
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43db75ee$0$38652$edfadb0f@dread12.news.tele.dk>
Jens Axel S�gaard wrote:
> Pascal Costanza wrote:
>> Jens Axel S�gaard wrote:

>> Strictly speaking, syntax-case macros are more powerful than CL 
>> macros. Wrt accidental/intentional variable capture, they are both on 
>> par. Wrt. referential transparency, Common Lisp is less expressive.
> 
> I could have sworn you found a solution the last time we discussed this.
> 
> <http://groups.google.com/group/comp.lang.lisp/msg/4d905c8db6739216?hl=en&>

Rereading the thread (which I learned a lot from - there were many 
well-written posts), I think the solution I couldn't remember were Kaz's
(he uses packages).

-- 
Jens Axel S�gaard
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <441cp1F1pinosU1@individual.net>
Jens Axel S�gaard wrote:
> Pascal Costanza wrote:
> 
>> Jens Axel S�gaard wrote:
>>
>>> It's the "more or less". The 'syntax-case' and the CL
>>> macro system are equally powerful.
>>
>> Strictly speaking, syntax-case macros are more powerful than CL 
>> macros. Wrt accidental/intentional variable capture, they are both on 
>> par. Wrt. referential transparency, Common Lisp is less expressive.
> 
> I could have sworn you found a solution the last time we discussed this.
> 
> <http://groups.google.com/group/comp.lang.lisp/msg/4d905c8db6739216?hl=en&>

That one doesn't handle block names or go tags. It only shows 
referential transparency for variables.

>  > A chieving referential transparency for catch tags is probably also
>  > straightforward. However, I don't have a good idea how to achieve it
>  > for block names and go tags - this seems to be impossible without
>  > locally redefining return-from or go respectively, and that is
>  > prohibited by ANSI Common Lisp. So in this sense, syntax-case is
>  > strictly more expressive (given that block names and go tags are
>  > implemented in Scheme by way of call/cc and stored in variables as
>  > well).
> 
> My CommonLisp skills isn't sufficient to understand the finer details of
> your macros, but I get the point: referential transparency is harder to
> achieve than hygiene.

Right.

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87psmcrp5s.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:

> Jens Axel S�gaard wrote:
>
>> It's the "more or less". The 'syntax-case' and the CL
>> macro system are equally powerful.
>
> Strictly speaking, syntax-case macros are more powerful than CL
> macros. Wrt accidental/intentional variable capture, they are both on
> par. Wrt. referential transparency, Common Lisp is less expressive.

FSVO "powerful".  I don't know enough syntax-case to tell.  What I
know is that they feel like the Turing equivalence of C++ template to me.


To take a simple example:

(define-syntax -->
   (syntax-rules ()
     ((_ . original)
      (-->helper () original))))

(define-syntax -->helper
    (syntax-rules ()
      ((_ pairs (x0 y0 . more))
       (-->helper ((x0 y0) . pairs) more))
      ((_ pairs body)
       (let pairs . body))))



(defmacro --> (&rest [var-val]*-body)
  `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
               collect (list var val))
     ,@(last [var-val]*-body)))


Perhaps scheme's syntax-case is more powerful, but Common Lisp is
definitely more concise, if not more expressive!

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You cannot really appreciate Dilbert unless you read it in the
original Klingon"
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43dbf194$0$38677$edfadb0f@dread12.news.tele.dk>
Pascal Bourguignon wrote:

> (defmacro --> (&rest [var-val]*-body)
>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
>                collect (list var val))
>      ,@(last [var-val]*-body)))
> 
> 
> Perhaps scheme's syntax-case is more powerful, but Common Lisp is
> definitely more concise, if not more expressive!

The above solution used syntax-rules and not syntax-case. The
reason was, that I didn't know which implementation the poster
asking the question was using.

In syntax-case I would write this:

(define-syntax (--> stx)
   (syntax-case stx ()
     [(--> var-val ... last)
      #`(let #,(list->pairings (syntax->list #'(var-val ...)))
          last)]))

Where list->pairings take a list of elements and pairs the
elements, e.g. (list->pairings (list 1 2 3 4)) ==> ((1 2) (3 4)).
How to implement it is not terrible important, one could
use match

(require-for-syntax (lib "match.ss"))
(begin-for-syntax
   (define (list->pairings l)
     (match l
       [(x y . more) (cons (list x y)
                       (list->pairings more))]
       [()            '()])))

or named let

(begin-for-syntax
   (define (list->pairings l)
     (if (null? l)
         '()
         (cons (list (car l) (cadr l))
               (list->pairings (cddr l))))))

or even a port of the CL's loop

<http://cvs.sourceforge.net/viewcvs.py/commonmusic/cm/src/loop.scm?rev=1.6&view=auto>

-- 
Jens Axel S�gaard
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e1195b$0$38670$edfadb0f@dread12.news.tele.dk>
Jens Axel S�gaard wrote:
> Pascal Bourguignon wrote:
> 
>> (defmacro --> (&rest [var-val]*-body)
>>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function 
>> cddr)
>>                collect (list var val))
>>      ,@(last [var-val]*-body)))
>>
>>
>> Perhaps scheme's syntax-case is more powerful, but Common Lisp is
>> definitely more concise, if not more expressive!
> 
> The above solution used syntax-rules and not syntax-case. The
> reason was, that I didn't know which implementation the poster
> asking the question was using.
> 
> In syntax-case I would write this:
> 
> (define-syntax (--> stx)
>   (syntax-case stx ()
>     [(--> var-val ... last)
>      #`(let #,(list->pairings (syntax->list #'(var-val ...)))
>          last)]))

I was too fast. I forgot to check for errors. Here is a better
version:

(define-syntax (--> stx)
   (define (list->pairings l)
     (if (null? l) '()
         (cons (list (car l) (cadr l))
               (list->pairings (cddr l)))))
   (syntax-case stx ()
     [(--> . var-or-exprs)
      (even? (length (syntax->list #'var-or-exprs)))
      (raise-syntax-error #f
      "Bad syntax, (--> <var> <expr> ... <body-expr>) expected" stx stx)]
     [(--> var-or-expr ... body)
      (let ([var/exprs
             (list->pairings (syntax->list #'(var-or-expr ...)))])
        (syntax-case var/exprs ()
          [((v e) ...)
           (let ([vars (syntax->list #'(v ...))])
             (for-each
               (lambda (v)
                 (unless (identifier? v)
                   (raise-syntax-error #f
                                       "identifier expected, " stx v)))
               vars)
             (let ([t (check-duplicate-identifier vars)])
               (when t
                 (raise-syntax-error #f
                                  "duplicate identifier found, " stx t)))
             #`(let ((v e) ...)
                 body))]))]))

This seems terrible at first sight, but the error reporting is much
better:

(--> 1 2)
; The whole form is highlighted, the error message:
; -->: Bad syntax, (--> <var> <expr> ... <body-expr>)
;      expected in: (--> 1 2)

(--> 1 2 3)
; The 1 is highlighted, the error message is:
; error message: -->: identifier expected,  in: 1

(--> a 1 a 2 42)
; The second a is highlighted, the error message is
;  -->: duplicate identifier found,  in: a

It even works, when the user got the syntax right!

(--> a 1 b 2 (+ a b))
; => 3


-- 
Jens Axel S�gaard
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138850931.227763.99240@g49g2000cwa.googlegroups.com>
Jens Axel Søgaard wrote:
> Jens Axel Søgaard wrote:
> > Pascal Bourguignon wrote:
> >
> >> (defmacro --> (&rest [var-val]*-body)
> >>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function
> >> cddr)
> >>                collect (list var val))
> >>      ,@(last [var-val]*-body)))


   [...]

> This seems terrible at first sight, but the error reporting is much
> better:

Indeed, the error reporting is impressive!  That seems a very practical
advantage of syntax-case over CL macros.  I think.  I don't comprehend
the actual syntax-case definition but writing a lengthier macro in
exchange for fancy error reporting seems like a good tradeoff to me.

Is it the case the CL macros are not capable of such fancy error
reporting?  I've read a bit about CL macros but my inability to follow
Pascal's example above shows I still have much to learn before I can
even say I know all of the basics of CL macros, much less the advanced
stuff.


> It even works, when the user got the syntax right!
>
> (--> a 1 b 2 (+ a b))
> ; => 3

OK, I can now see the intent of the macro is similar to a 'let' form.

Thanks!
  --jfc
From: Geoffrey Summerhayes
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <tUgEf.7114$Sk1.240877@news20.bellglobal.com>
"funkyj" <······@gmail.com> wrote in message ····························@g49g2000cwa.googlegroups.com...
>
> Indeed, the error reporting is impressive!  That seems a very practical
> advantage of syntax-case over CL macros.  I think.  I don't comprehend
> the actual syntax-case definition but writing a lengthier macro in
> exchange for fancy error reporting seems like a good tradeoff to me.
>
> Is it the case the CL macros are not capable of such fancy error
> reporting?  I've read a bit about CL macros but my inability to follow
> Pascal's example above shows I still have much to learn before I can
> even say I know all of the basics of CL macros, much less the advanced
> stuff.

No, a macro is just Lisp code that returns code,
so anything you can write in Lisp can go in a macro.

For example, the variable error (--> 1 2 3) will be
signalled by LET after the expansion, but it's easy
enough to include in the LOOP, for example:

(loop for (var val)
      on (butlast [var-val]*-body)
      by (function cddr)
      if (symbolp var)
          collect (list var val)
      else do
        (error "Error: Syntactic error in form ~S:~%   ~
                ~S is not a variable."
            (cons '--> [var-val]*-body) var))

---
Geoff 
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <44e20cF1mn0cU1@individual.net>
Jens Axel S�gaard wrote:
> Jens Axel S�gaard wrote:
> 
>> Pascal Bourguignon wrote:
>>
>>> (defmacro --> (&rest [var-val]*-body)
>>>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by 
>>> (function cddr)
>>>                collect (list var val))
>>>      ,@(last [var-val]*-body)))
>>>
>>>
>>> Perhaps scheme's syntax-case is more powerful, but Common Lisp is
>>> definitely more concise, if not more expressive!
>>
>>
>> The above solution used syntax-rules and not syntax-case. The
>> reason was, that I didn't know which implementation the poster
>> asking the question was using.
>>
>> In syntax-case I would write this:
>>
>> (define-syntax (--> stx)
>>   (syntax-case stx ()
>>     [(--> var-val ... last)
>>      #`(let #,(list->pairings (syntax->list #'(var-val ...)))
>>          last)]))
> 
> 
> I was too fast. I forgot to check for errors. Here is a better
> version:
> 
> (define-syntax (--> stx)
>   (define (list->pairings l)
>     (if (null? l) '()
>         (cons (list (car l) (cadr l))
>               (list->pairings (cddr l)))))
>   (syntax-case stx ()
>     [(--> . var-or-exprs)
>      (even? (length (syntax->list #'var-or-exprs)))
>      (raise-syntax-error #f
>      "Bad syntax, (--> <var> <expr> ... <body-expr>) expected" stx stx)]
>     [(--> var-or-expr ... body)
>      (let ([var/exprs
>             (list->pairings (syntax->list #'(var-or-expr ...)))])
>        (syntax-case var/exprs ()
>          [((v e) ...)
>           (let ([vars (syntax->list #'(v ...))])
>             (for-each
>               (lambda (v)
>                 (unless (identifier? v)
>                   (raise-syntax-error #f
>                                       "identifier expected, " stx v)))
>               vars)
>             (let ([t (check-duplicate-identifier vars)])
>               (when t
>                 (raise-syntax-error #f
>                                  "duplicate identifier found, " stx t)))
>             #`(let ((v e) ...)
>                 body))]))]))
> 
> This seems terrible at first sight, but the error reporting is much
> better:
> 
> (--> 1 2)
> ; The whole form is highlighted, the error message:
> ; -->: Bad syntax, (--> <var> <expr> ... <body-expr>)
> ;      expected in: (--> 1 2)
> 
> (--> 1 2 3)
> ; The 1 is highlighted, the error message is:
> ; error message: -->: identifier expected,  in: 1
> 
> (--> a 1 a 2 42)
> ; The second a is highlighted, the error message is
> ;  -->: duplicate identifier found,  in: a
> 
> It even works, when the user got the syntax right!
> 
> (--> a 1 b 2 (+ a b))
> ; => 3

Here is the same thing as a defmacro, including all the error messages:

(defmacro --> (&whole form &body body)
   (unless (oddp (length body))
     (error "~S only contains bindings but no final expression." form))
   (loop for (var expression) on (butlast body) by #'cddr
         unless (symbolp var) do (error "~S is not a variable in ~S." 
var form)
         when (member var seen-variables) do (error "Variable ~S appears 
more than once in ~S." var form)
         collect var into seen-variables
         collect `(,var ,expression) into bindings
         finally (return `(let ,bindings ,@(last body)))))


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87y80tnajs.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:
>> I was too fast. I forgot to check for errors. Here is a better
>> version:
>> (define-syntax (--> stx)
>>   (define (list->pairings l)
>>     (if (null? l) '()
>>         (cons (list (car l) (cadr l))
>>               (list->pairings (cddr l)))))
>>   (syntax-case stx ()
>>     [(--> . var-or-exprs)
>>      (even? (length (syntax->list #'var-or-exprs)))
>>      (raise-syntax-error #f
>>      "Bad syntax, (--> <var> <expr> ... <body-expr>) expected" stx stx)]
>>     [(--> var-or-expr ... body)
>>      (let ([var/exprs
>>             (list->pairings (syntax->list #'(var-or-expr ...)))])
>>        (syntax-case var/exprs ()
>>          [((v e) ...)
>>           (let ([vars (syntax->list #'(v ...))])
>>             (for-each
>>               (lambda (v)
>>                 (unless (identifier? v)
>>                   (raise-syntax-error #f
>>                                       "identifier expected, " stx v)))
>>               vars)
>>             (let ([t (check-duplicate-identifier vars)])
>>               (when t
>>                 (raise-syntax-error #f
>>                                  "duplicate identifier found, " stx t)))
>>             #`(let ((v e) ...)
>>                 body))]))]))
>
> Here is the same thing as a defmacro, including all the error messages:
>
> (defmacro --> (&whole form &body body)
>    (unless (oddp (length body))
>      (error "~S only contains bindings but no final expression." form))
>    (loop for (var expression) on (butlast body) by #'cddr
>          unless (symbolp var) do (error "~S is not a variable in ~S."
>          var form)
>          when (member var seen-variables) do (error "Variable ~S
>          appears more than once in ~S." var form)
>          collect var into seen-variables
>          collect `(,var ,expression) into bindings
>          finally (return `(let ,bindings ,@(last body)))))

I believe my point is clear: Common Lisp defmacro is at least twice as
expressive (concise) as Scheme define-syntax.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You cannot really appreciate Dilbert unless you read it in the
original Klingon"
From: Andre
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43E21C15.59FFA084@het.brown.edu>
Pascal Bourguignon wrote:
 
> > (defmacro --> (&whole form &body body)
> >    (unless (oddp (length body))
> >      (error "~S only contains bindings but no final expression." form))
> >    (loop for (var expression) on (butlast body) by #'cddr
> >          unless (symbolp var) do (error "~S is not a variable in ~S."
> >          var form)
> >          when (member var seen-variables) do (error "Variable ~S
> >          appears more than once in ~S." var form)
> >          collect var into seen-variables
> >          collect `(,var ,expression) into bindings
> >          finally (return `(let ,bindings ,@(last body)))))
> 
> I believe my point is clear: Common Lisp defmacro is at least twice as
> expressive (concise) as Scheme define-syntax.
 
Here is a roughly equivalent, concise version in Scheme using SRFI-72 
(available, for example, in Chicken and Common Larceny).  

(define-syntax (--> . body)
  (let loop ((body     body)
             (seen     '())
             (bindings (syntax ())))
    (cond ((null? body)       (syntax-error "Form contains no final expression"))
          ((null? (cdr body)) (quasisyntax (let ,bindings ,@body)))
          (else
           (let ((var (car body))
                 (exp (cadr body)))
             (if (not (identifier? var))
               (syntax-error var "is not an identifier"))
             (if (member var seen bound-identifier=?)
               (syntax-error var "appears more than once in form"))
             (loop (cddr body)
                   (cons var seen)
                   (quasisyntax ((,var ,exp) ,@bindings))))))))

With minor changes, something similar will work for, e.g., PLT's syntax-case.  

Regards
Andre
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e228e4$0$38684$edfadb0f@dread12.news.tele.dk>
Andre wrote:

> Here is a roughly equivalent, concise version in Scheme using SRFI-72 
> (available, for example, in Chicken and Common Larceny).  
> 
> (define-syntax (--> . body)
>   (let loop ((body     body)
>              (seen     '())
>              (bindings (syntax ())))
>     (cond ((null? body)       (syntax-error "Form contains no final expression"))
>           ((null? (cdr body)) (quasisyntax (let ,bindings ,@body)))
>           (else
>            (let ((var (car body))
>                  (exp (cadr body)))
>              (if (not (identifier? var))
>                (syntax-error var "is not an identifier"))
>              (if (member var seen bound-identifier=?)
>                (syntax-error var "appears more than once in form"))
>              (loop (cddr body)
>                    (cons var seen)
>                    (quasisyntax ((,var ,exp) ,@bindings))))))))
> 
> With minor changes, something similar will work for, e.g., PLT's syntax-case.  

The only changes needed is to use #, and #,@ instead of , and ,@ .
And change syntax-error to raise-syntax-error.


(require-for-syntax (lib "stx.ss" "syntax")
                     (only (lib "1.ss" "srfi") member))

(define-syntax (--> stx)
   (let loop ((body     (stx-cdr stx))
              (seen     '())
              (bindings (syntax ())))
     (cond ((null? body)(raise-syntax-error #f "Form contains no final 
expression" stx))
           ((null? (cdr body)) (quasisyntax (let #,bindings #,@body)))
           (else
            (let ((var (car body))
                  (exp (cadr body)))
              (if (not (identifier? var))
                  (raise-syntax-error #f "is not an identifier" stx var))
              (if (member var seen bound-identifier=?)
                  (raise-syntax-error #f "appears more than once in 
form" stx var))
              (loop (cddr body)
                    (cons var seen)
                    (quasisyntax ((#,var #,exp) #,@bindings))))))))

-- 
Jens Axel S�gaard
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e216f3$0$38662$edfadb0f@dread12.news.tele.dk>
Pascal Bourguignon wrote:

> I believe my point is clear: Common Lisp defmacro is at least twice as
> expressive (concise) as Scheme define-syntax.

Not at all - it is loop that makes Constances code small, not
defmacro.

-- 
Jens Axel S�gaard
From: jayessay
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m38xst8w7l.fsf@rigel.goldenthreadtech.com>
Jens Axel S�gaard <······@soegaard.net> writes:

> Pascal Bourguignon wrote:
> 
> > I believe my point is clear: Common Lisp defmacro is at least twice as
> > expressive (concise) as Scheme define-syntax.
> 
> Not at all - it is loop that makes Constances code small, not
> defmacro.

Actually, it is that macros (via defmacro) are just Lisp functions,
and thus can use loop or whatever else to make the code as concise and
clear as possible.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e25306$0$38669$edfadb0f@dread12.news.tele.dk>
jayessay wrote:
> Jens Axel S�gaard <······@soegaard.net> writes:
>>Pascal Bourguignon wrote:
>>
>>>I believe my point is clear: Common Lisp defmacro is at least twice as
>>>expressive (concise) as Scheme define-syntax.
>>
>>Not at all - it is loop that makes Constances code small, not
>>defmacro.
> 
> Actually, it is that macros (via defmacro) are just Lisp functions,
> and thus can use loop or whatever else to make the code as concise and
> clear as possible.

Syntax-case macros are also just functions.

-- 
Jens Axel S�gaard
From: jayessay
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m3vevx7ehr.fsf@rigel.goldenthreadtech.com>
Jens Axel S�gaard <······@soegaard.net> writes:

> jayessay wrote:
> > Jens Axel S�gaard <······@soegaard.net> writes:
> >>Pascal Bourguignon wrote:
> >>
> >>>I believe my point is clear: Common Lisp defmacro is at least twice as
> >>>expressive (concise) as Scheme define-syntax.
> >>
> >>Not at all - it is loop that makes Constances code small, not
> >>defmacro.
> > Actually, it is that macros (via defmacro) are just Lisp functions,
> > and thus can use loop or whatever else to make the code as concise and
> > clear as possible.
> 
> Syntax-case macros are also just functions.

I didn't intend to say otherwise.

/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e26133$0$38642$edfadb0f@dread12.news.tele.dk>
jayessay wrote:
> Jens Axel S�gaard <······@soegaard.net> writes:
>>jayessay wrote:
>>>Jens Axel S�gaard <······@soegaard.net> writes:
>>>>Pascal Bourguignon wrote:

>>>>>I believe my point is clear: Common Lisp defmacro is at least twice as
>>>>>expressive (concise) as Scheme define-syntax.
>>>>
>>>>Not at all - it is loop that makes Constances code small, not
>>>>defmacro.
>>>
>>>Actually, it is that macros (via defmacro) are just Lisp functions,
>>>and thus can use loop or whatever else to make the code as concise and
>>>clear as possible.
>>
>>Syntax-case macros are also just functions.
> 
> 
> I didn't intend to say otherwise.

The quoted context and the "actually" didn't make it crystal clear :-)

-- 
Jens Axel S�gaard
From: jayessay
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m3r76l7a3x.fsf@rigel.goldenthreadtech.com>
Jens Axel S�gaard <······@soegaard.net> writes:

> jayessay wrote:
> > Jens Axel S�gaard <······@soegaard.net> writes:
> >>jayessay wrote:
> >>>Jens Axel S�gaard <······@soegaard.net> writes:
> >>>>Pascal Bourguignon wrote:
> 
> >>>>>I believe my point is clear: Common Lisp defmacro is at least twice as
> >>>>>expressive (concise) as Scheme define-syntax.
> >>>>
> >>>>Not at all - it is loop that makes Constances code small, not
> >>>>defmacro.
> >>>
> >>>Actually, it is that macros (via defmacro) are just Lisp functions,
> >>>and thus can use loop or whatever else to make the code as concise and
> >>>clear as possible.
> >>
> >>Syntax-case macros are also just functions.
> > I didn't intend to say otherwise.
> 
> The quoted context and the "actually" didn't make it crystal clear :-)
> 

Right.  This is Usenet! :-)


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Ulrich Hobelmann
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <44ep37F1gtcqU1@individual.net>
Jens Axel S�gaard wrote:
> Pascal Bourguignon wrote:
> 
>> I believe my point is clear: Common Lisp defmacro is at least twice as
>> expressive (concise) as Scheme define-syntax.
> 
> Not at all - it is loop that makes Constances code small, not
> defmacro.

But LOOP wouldn't work with syntax-rules, would it?

-- 
Suffering from Gates-induced brain leakage...
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e252d4$0$38669$edfadb0f@dread12.news.tele.dk>
Ulrich Hobelmann wrote:
> Jens Axel S�gaard wrote:
>> Pascal Bourguignon wrote:
>>
>>> I believe my point is clear: Common Lisp defmacro is at least twice as
>>> expressive (concise) as Scheme define-syntax.
>>
>> Not at all - it is loop that makes Constances code small, not
>> defmacro.
> 
> But LOOP wouldn't work with syntax-rules, would it?

Nope - for that you need something syntax-case or similar.

-- 
Jens Axel S�gaard
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e2259d$0$38723$edfadb0f@dread12.news.tele.dk>
Pascal Costanza wrote:

> Here is the same thing as a defmacro, including all the error messages:
> 
> (defmacro --> (&whole form &body body)
>   (unless (oddp (length body))
>     (error "~S only contains bindings but no final expression." form))
>   (loop for (var expression) on (butlast body) by #'cddr
>         unless (symbolp var) do 
 >                (error "~S is not a variable in ~S." var form)
>         when (member var seen-variables) do 
 >             (error "Variable ~S appears more than once in ~S."
 >                    var form)
>         collect var into seen-variables
>         collect `(,var ,expression) into bindings
>         finally (return `(let ,bindings ,@(last body)))))

Nice. I tried it in Allegro. The error messages are almost the same.
There is a small difference though. E.g. in

     (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)

the error becomes:

   Error: 2 is not a variable in (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)

That is, the whole form is shown. In the syntax-case version
the particular offending instance of 2 is highlighted.

Bourguignon were right that my first version weren't that
concise. The blame is not syntax-case, but mine (or Scheme
for not including loops). Inspired by Constanzas solution here
is an attempt to use srfi-42 loops in stead of CL loops:

(define-syntax (--> stx)
   (let* ([form  (syntax->list stx)]
          [body  (cdr form)]
          [seen  '()])
     (unless (even? (length form))
       (raise-syntax-error #f
          "Bindings only, expected a final expression." stx))
     #`(let #,(list-ec
              (:pairs-by var-exprs (drop-right body 1) cddr)
              (:match (var expr . _) var-exprs)
              (begin
                (unless (identifier? var)
                  (raise-syntax-error #f
                     "identifier expected: " stx var))
                (when (member var seen bound-identifier=?)
                  (display seen)
                  (raise-syntax-error #f "duplicate identifier" stx var))
                (set! seen (cons var seen)))
              (list var expr))
         #,(last body))))

Here drop-right, member and last is from srfi-1.

The generators :pairs-by and :match is from my soon-to-be-released
tutorial for srfi-42 (see
<http://list.cs.brown.edu/pipermail/plt-scheme/2006-February/011394.html>
for the :match generator).

-- 
Jens Axel S�gaard
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <44ev7pF1s15kU1@individual.net>
Jens Axel S�gaard wrote:
> Pascal Costanza wrote:
> 
>> Here is the same thing as a defmacro, including all the error messages:
>>
>> (defmacro --> (&whole form &body body)
>>   (unless (oddp (length body))
>>     (error "~S only contains bindings but no final expression." form))
>>   (loop for (var expression) on (butlast body) by #'cddr
>>         unless (symbolp var) do 
> 
>  >                (error "~S is not a variable in ~S." var form)
> 
>>         when (member var seen-variables) do 
> 
>  >             (error "Variable ~S appears more than once in ~S."
>  >                    var form)
> 
>>         collect var into seen-variables
>>         collect `(,var ,expression) into bindings
>>         finally (return `(let ,bindings ,@(last body)))))
> 
> 
> Nice. I tried it in Allegro. The error messages are almost the same.
> There is a small difference though. E.g. in
> 
>     (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
> 
> the error becomes:
> 
>   Error: 2 is not a variable in (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)

Hm, not sure whether that's really important, but here we go ;)

(defmacro --> (&whole form &body body)
   (flet ((mark-pos (list pos)
            (loop for elm in list
                  for count from 0
                  when (eql count pos) collect '=>
                  when (eql count (1+ pos)) collect '<=
                  collect elm)))
     (unless (oddp (length body))
       (error "~S only contains bindings but no final expression." form))
     (loop for (var expression) on (butlast body) by #'cddr
           for pos from 0 by 2
           unless (symbolp var) do (error "~S is not a variable in ~S." 
var (mark-pos form pos))
           when (member var seen-variables) do (error "Variable ~S 
appears more than once in ~S." var (mark-pos form pos))
           collect var into seen-variables
           collect `(,var ,expression) into bindings
           finally (return `(let ,bindings ,@(last body))))))


 > (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)

Error: 2 is not a variable in (--> A 2 B 2 C 2 D => 2 <= 2 2 F 2 G 2 2).

> In the syntax-case version
> the particular offending instance of 2 is highlighted.

Is this a feature of syntax case, or is this a feature of the 
development environment? Just curious.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e260ab$0$38642$edfadb0f@dread12.news.tele.dk>
Pascal Costanza wrote:
> Jens Axel S�gaard wrote:
>> Pascal Costanza wrote:
>>
>>> Here is the same thing as a defmacro, including all the error messages:

>> Nice. I tried it in Allegro. The error messages are almost the same.
>> There is a small difference though. E.g. in
>>
>>     (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
>>
>> the error becomes:
>>
>>   Error: 2 is not a variable in (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
> 
> 
> Hm, not sure whether that's really important, but here we go ;)
> 
> (defmacro --> (&whole form &body body)
>   (flet ((mark-pos (list pos)
>            (loop for elm in list
>                  for count from 0
>                  when (eql count pos) collect '=>
>                  when (eql count (1+ pos)) collect '<=
>                  collect elm)))
>     (unless (oddp (length body))
>       (error "~S only contains bindings but no final expression." form))
>     (loop for (var expression) on (butlast body) by #'cddr
>           for pos from 0 by 2
>           unless (symbolp var) do (error "~S is not a variable in ~S." 
> var (mark-pos form pos))
>           when (member var seen-variables) do (error "Variable ~S 
> appears more than once in ~S." var (mark-pos form pos))
>           collect var into seen-variables
>           collect `(,var ,expression) into bindings
>           finally (return `(let ,bindings ,@(last body))))))
> 
> 
>  > (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
> 
> Error: 2 is not a variable in (--> A 2 B 2 C 2 D => 2 <= 2 2 F 2 G 2 2).

That's much better. Indicating the precise error location becomes
important, when the macros/programs are large.

>> In the syntax-case version
>> the particular offending instance of 2 is highlighted.
> 
> 
> Is this a feature of syntax case, or is this a feature of the 
> development environment? Just curious.

This is a feature of syntax-case that the development environment
uses. The reader returns a syntax-object representing the form.
The syntax-object contains properties such as the file name,
line number and column position of the form it represents. The #'
means quote-syntax and #'(+ a b) evaluates to a syntax-object 
representing the expression (+ a b).

 > (syntax-column                        #'(+ a b))
42

The function syntax->list takes a syntax-list (i.e. a syntax-object
representing a list) and returns a list of syntax-objects representing
its elements.

 > (syntax->list #'(+ a b))
(.#<syntax:28:19> .#<syntax:28:21> .#<syntax:28:23>)

[DrScheme shows a graphical representation of the syntax-objects,
  that one can open and examine. When copied to the mail program
  it looks a bit pale]

A macro can add new properties to the syntax-objects in question,
or simply read the ones put there by the reader.


 > (syntax-column (caddr   (syntax->list #'(+ a b))))
47
 > (syntax-column (cadr    (syntax->list #'(+ a b))))
45
 > (syntax-column (car     (syntax->list #'(+ a b))))
43
 > (syntax-column          (syntax->list #'(+ a b)))
. syntax-column: expects argument of type <syntax>; given 
(#<syntax:22:43> #<syntax:22:45> #<syntax:22:47>)


 > (map syntax-column      (syntax->list #'(+ a b)))
(43 45 47)


Normally though the source location information is only
used by raise-syntax-error, which besides the error message takes
the offending form and the specific subform as arguments. E.g in
the call

   (raise-syntax-error #f "duplicate identifier" stx var)

the stx is used to extract the name of the form, and var contains
the the precise location of the offending variable.
Raise-syntax-error will print an error message in the REPL such as

    -->: duplicate identifier,  in: a

and throw an excpetion. In the exception the source location is
stored. If used in the development environment (DrScheme) the
exception is caught, and the file containing the offending piece
of syntax is opened, the cursor is positioned and the syntax
is colored red.

That is, using an abstract datatype for syntax buys you easy
handling of source location - the price you pay is that you
have to think about whether you are handling, say, a
"syntax object representing a list" or simple a "list".

-- 
Jens Axel S�gaard
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <44f637F1kkvlU3@individual.net>
Jens Axel S�gaard wrote:
> Pascal Costanza wrote:
> 
>> Jens Axel S�gaard wrote:
>>
>>> In the syntax-case version
>>> the particular offending instance of 2 is highlighted.
>>
>> Is this a feature of syntax case, or is this a feature of the 
>> development environment? Just curious.> 
> 
> This is a feature of syntax-case that the development environment
> uses. The reader returns a syntax-object representing the form.
> The syntax-object contains properties such as the file name,
> line number and column position of the form it represents. The #'
> means quote-syntax and #'(+ a b) evaluates to a syntax-object 
> representing the expression (+ a b).
> 
>  > (syntax-column                        #'(+ a b))
> 42
[...]

Neat!

> That is, using an abstract datatype for syntax buys you easy
> handling of source location - the price you pay is that you
> have to think about whether you are handling, say, a
> "syntax object representing a list" or simple a "list".

OK, very interesting. Thanks a lot for the explanation!


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Raffael Cavallaro
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <2006020311260975249-raffaelcavallaro@pasdespamsilvousplaitmaccom>
On 2006-02-02 12:52:55 -0500, Pascal Costanza <··@p-cos.net> said:

> (defmacro --> (&whole form &body body)
>    (flet ((mark-pos (list pos)
>             (loop for elm in list
>                   for count from 0
>                   when (eql count pos) collect '=>
>                   when (eql count (1+ pos)) collect '<=
>                   collect elm)))
>      (unless (oddp (length body))
>        (error "~S only contains bindings but no final expression." form))
>      (loop for (var expression) on (butlast body) by #'cddr
>            for pos from 0 by 2
>            unless (symbolp var) do (error "~S is not a variable in ~S." 
> var (mark-pos form pos))
>            when (member var seen-variables) do (error "Variable ~S 
> appears more than once in ~S." var (mark-pos form pos))
>            collect var into seen-variables
>            collect `(,var ,expression) into bindings
>            finally (return `(let ,bindings ,@(last body))))))
> 
> 
>  > (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
> 
> Error: 2 is not a variable in (--> A 2 B 2 C 2 D => 2 <= 2 2 F 2 G 2 2).

but:

? (-->
      x 1
      y 2
      4 z
      q 'bert
      ig 'natz
      (* x y z q ig))
> Error in process listener(1): 4 is not a variable in (--> X 1 Y => 2 
<= 4 Z Q 'BERT IG 'NATZ (* X Y Z Q IG)).
> While executing: -->

IOW, the wrong position is marked due to an off-by-one error because 
you are looping on (butlast body) but marking the whole form using a 
position in (butlast body).

Changing it to (mark-pos form (1+ pos)) should work:

? (defmacro --> (&whole form &body body)
  (flet ((mark-pos (list pos)
           (loop for elm in list
                 for count from 0
                 when (eql count pos) collect '=>
                 when (eql count (1+ pos)) collect '<=
                 collect elm)))
    (unless (oddp (length body))
      (error "~S only contains bindings but no final expression." form))
    (loop for (var expression) on (butlast body) by #'cddr
          for pos from 0 by 2
          unless (symbolp var) do (error "~S is not a variable in ~S." 
var (mark-pos form (1+ pos)))
          when (member var seen-variables) do (error "Variable ~S 
appears more than once in ~S." var (mark-pos form (1+ pos)))
          collect var into seen-variables
          collect `(,var ,expression) into bindings
          finally (return `(let ,bindings ,@(last body))))))
-->
? (--> A 2 B 2 C 2 D 2 2 2 F 2 G 2 2)
> Error in process listener(1): 2 is not a variable in (--> A 2 B 2 C 2 
D 2 => 2 <= 2 F 2 G 2 2).
> While executing: -->
> Type :POP to abort.
Type :? for other options.
1 > :pop

? (-->
      x 1
      y 2
      4 z
      q 'bert
      ig 'natz
      (* x y z q ig))
> Error in process listener(1): 4 is not a variable in (--> X 1 Y 2 => 
4 <= Z Q 'BERT IG 'NATZ (* X Y Z Q IG)).
> While executing: -->
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138849838.866444.58120@g49g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:

> To take a simple example:

Heh heh, not simple enough for me.  Can you start by telling me when
the intent of "-->" is?  I don' t know either syntax-rules nor CL
macros well enough to just figure it out from reading your definitions.

> (define-syntax -->
>    (syntax-rules ()
>      ((_ . original)
>       (-->helper () original))))
>
> (define-syntax -->helper
>     (syntax-rules ()
>       ((_ pairs (x0 y0 . more))
>        (-->helper ((x0 y0) . pairs) more))
>       ((_ pairs body)
>        (let pairs . body))))

> (defmacro --> (&rest [var-val]*-body)
>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
>                collect (list var val))
>      ,@(last [var-val]*-body)))
>

Hmm, the whole "[var-val]*" thing is greek to me.  Is this aspect of CL
macros covered in PCL or On Lisp?

Also, just reading over R5RS is definitely not enough for me follow
syntax-rule example you give.  I also recently looked at 'Chez Scheme
Users Guide, Ch 9' for a description of syntax-case macros and my head
almost exploded.  I definitely need to get a scheme implementation to
play around with.

Regards,
  --jfc

P.S. thanks for carrying the discussion forward.  I expect with not too
much study I should be able to follow your intent above.

> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
>
> "You cannot really appreciate Dilbert unless you read it in the
> original Klingon"
From: Bill Atkins
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <873bj2o1ww.fsf@rpi.edu>
"funkyj" <······@gmail.com> writes:

> Pascal Bourguignon wrote:
>
>> To take a simple example:
>
> Heh heh, not simple enough for me.  Can you start by telling me when
> the intent of "-->" is?  I don' t know either syntax-rules nor CL
> macros well enough to just figure it out from reading your definitions.
>
>> (define-syntax -->
>>    (syntax-rules ()
>>      ((_ . original)
>>       (-->helper () original))))
>>
>> (define-syntax -->helper
>>     (syntax-rules ()
>>       ((_ pairs (x0 y0 . more))
>>        (-->helper ((x0 y0) . pairs) more))
>>       ((_ pairs body)
>>        (let pairs . body))))
>
>> (defmacro --> (&rest [var-val]*-body)
>>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
>>                collect (list var val))
>>      ,@(last [var-val]*-body)))
>>
>
> Hmm, the whole "[var-val]*" thing is greek to me.  Is this aspect of CL
> macros covered in PCL or On Lisp?

[var-val]*-body is simply a variable name.  It could just as easily
have been called x or the-body or anything else.  There is nothing
special about it.


> Also, just reading over R5RS is definitely not enough for me follow
> syntax-rule example you give.  I also recently looked at 'Chez Scheme
> Users Guide, Ch 9' for a description of syntax-case macros and my head
> almost exploded.  I definitely need to get a scheme implementation to
> play around with.

Try DrScheme or MIT-Scheme.

>
> Regards,
>   --jfc
>
> P.S. thanks for carrying the discussion forward.  I expect with not too
> much study I should be able to follow your intent above.
>
>> --
>> __Pascal Bourguignon__                     http://www.informatimago.com/
>>
>> "You cannot really appreciate Dilbert unless you read it in the
>> original Klingon"
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87u0bicsn8.fsf@thalassa.informatimago.com>
"funkyj" <······@gmail.com> writes:
>> (defmacro --> (&rest [var-val]*-body)
>>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
>>                collect (list var val))
>>      ,@(last [var-val]*-body)))
>>
>
> Hmm, the whole "[var-val]*" thing is greek to me.  Is this aspect of CL
> macros covered in PCL or On Lisp?


This is a self documenting identifier :-) 

   [var-val]*-body 

is just one identifier.  It has no syntaxtic structure.
In C, you would need to write insteed:

   zero_or_more_couples_of_var_and_val_then_body

or something.  But since most special characters are not special in
lisp, you can use them in identifiers.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Logiciels libres : nourris au code source sans farine animale."
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138864957.563135.300070@g49g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:
> "funkyj" <······@gmail.com> writes:
> >> (defmacro --> (&rest [var-val]*-body)
> >>   `(let ,(loop for (var val) on (butlast [var-val]*-body) by (function cddr)
> >>                collect (list var val))
> >>      ,@(last [var-val]*-body)))
> >>
> >
> > Hmm, the whole "[var-val]*" thing is greek to me.  Is this aspect of CL
> > macros covered in PCL or On Lisp?
>
>
> This is a self documenting identifier :-)
>
>    [var-val]*-body
>
> is just one identifier.  It has no syntaxtic structure.
> In C, you would need to write insteed:

DOH!  I've gotten used to !?->* in identifiers but the square brackets
threw me :^).

is the "(var val)" in (loop for (var val) on (butlast ..." a
destructuring bind over elements of [var-val]*-body?  I'm not
conversant in all the variants of CL "loop" form.

Also, In the syntax-case example by Jens, I'm guessing the square
brackets there DO have special meaning?  They seemed to be used in a
more paren grouping fashion.

Since CL lisp macros are really just regular lisp, executed at macro
expansion time, they seem to be easier to understand initially.  If you
can read regular common lisp, understand quasiquote and throw in some
gensyms you are there.

On the otherhand, the referential transparency of scheme macros is
appealing, although I don't know how much this actually buys on a
practical level.  Is any CL expert willing to own up to having been
bitten by lack of referential transparency in real life?  Being bitten
by a rarely occurring type of bug makes it all the harder to figure out
what went wrong...

I'll try to install a scheme environment this weekend, if for no other
reason than to learn more about syntax-rules and syntax case macros.

Cheers,
  --jfc
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <44e2gsF1mjaeU1@individual.net>
funkyj wrote:

> On the otherhand, the referential transparency of scheme macros is
> appealing, although I don't know how much this actually buys on a
> practical level.  Is any CL expert willing to own up to having been
> bitten by lack of referential transparency in real life?

I think this isn't a real issues for two reasons:

- If you define a global macro with defmacro, the global variables you 
can refer to are all special variables. Special variables behave 
differently anyway, you don't need to handle them specifically in 
macros. Global functions typically have (or should have) descriptive 
names so that it is unlikely that local function definitions capture 
them. Finally, if you are a slightly advanced Common Lisp hacker, you 
will partition your code into separate packages which means that your 
names are "hygienic" anyway. The code that a macro will expand into will 
refer to the names of the package in which it was defined, and if you 
have carefully exported only the public interface of your library, it's 
relatively straightforward to make your code safe in this regard.

- If you define local macros with macrolet, the names that such a macro 
refers to and the names that are introduced inside the scope of the 
macrolet are controlled by the same programmer anyway, so it's not too 
hard to take of choosing non-clashing names.

Referential transparency is more important in Scheme because there is no 
package system in Scheme to help you organize your code, and the module 
systems that you typically find in Scheme implementations are based on 
closures, so referential transparency cannot be based on names like in 
Common Lisp, but they must be based on bindings.

> Being bitten
> by a rarely occurring type of bug makes it all the harder to figure out
> what went wrong...

I'd say that if it were a real issue, people would do something about it. ;)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <873bj1op8t.fsf@thalassa.informatimago.com>
"funkyj" <······@gmail.com> writes:
>> This is a self documenting identifier :-)
>>
>>    [var-val]*-body
>>
>> is just one identifier.  It has no syntaxtic structure.
>> In C, you would need to write insteed:
>
> DOH!  I've gotten used to !?->* in identifiers but the square brackets
> threw me :^).

And I've even not used unicode :-)


> is the "(var val)" in (loop for (var val) on (butlast ..." a
> destructuring bind over elements of [var-val]*-body?  [...]

Yes.


> Also, In the syntax-case example by Jens, I'm guessing the square
> brackets there DO have special meaning?  They seemed to be used in a
> more paren grouping fashion.

No.  They have no different meaning than regular ().  It's just one of
those silly ideas scheme has.  For "pedagogical" reasons I believe. 

You can get the same in Common Lisp with:

(set-syntax-from-char #\[ #\()
(set-syntax-from-char #\] #\))
(set-macro-character #\[ (lambda (stream char) (read-delimited-list #\] stream t)))

Then:

[4]> (defun fact [x] [if (< x 1) 1 (* x [fact (1- x)])])
FACT
[5]> (fact 3)
6
[6]> 

As if matching corresponding parentheses mattered at all...


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You cannot really appreciate Dilbert unless you read it in the
original Klingon"
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87psm5vmqg.fsf@qrnik.zagroda>
"funkyj" <······@gmail.com> writes:

> Also, In the syntax-case example by Jens, I'm guessing the square
> brackets there DO have special meaning?  They seemed to be used in a
> more paren grouping fashion.

In some Scheme implementations [] are equivalent to (), and by
convention used in let, cond, do etc. for certain syntactic
groups.

In R5RS they are reserved for future extensions of the language,
along with { } |, so a portable code should not use them at all
(except strings and comments).

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43e1a574$0$38618$edfadb0f@dread12.news.tele.dk>
funkyj wrote:

> Also, just reading over R5RS is definitely not enough for me follow
> syntax-rule example you give.  I also recently looked at 'Chez Scheme
> Users Guide, Ch 9' for a description of syntax-case macros and my head
> almost exploded.  I definitely need to get a scheme implementation to
> play around with.

<http://www.drscheme.org>
<ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/pubs/iucstr356.ps.gz>

-- 
Jens Axel S�gaard
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87psmclgou.fsf@qrnik.zagroda>
"Kaz Kylheku" <········@gmail.com> writes:

> Should you have only static scope, because dynamic scope is
> introduces another symbol namespace?

Dynamic scope doesn't introduce another namespace. It can be expressed
using static scope in the core and little syntactic sugar over variable
references and assignments.

> Should I not be able to define a class FOO and a function FOO at the
> same time?

Should I not be able to write just FOO to refer to the function FOO,
or class FOO? Having separate namespaces for first-class entities
requires an extra syntax for passing them indirectly, both on the side
of making an expression which refers to it, and for using an entity
passed in a variable. This is ugly.

> Thus, given all these namespaces, why should two of them, namely
> object and function bindings, be merged together?

Not only them; at least some others too.

> Because functions are objects? Is that a good enough reason?

Yes.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87mzhglglw.fsf@qrnik.zagroda>
"Kaz Kylheku" <········@gmail.com> writes:

> Should you have only static scope, because dynamic scope is
> introduces another symbol namespace?

Dynamic scope doesn't introduce another namespace. It can be expressed
using static scope in the core and little syntactic sugar over variable
references and assignments.

> Should I not be able to define a class FOO and a function FOO at the
> same time?

Should I not be able to write just FOO to refer to the function FOO,
or class FOO? Having separate namespaces for first-class entities
requires an extra syntax for passing them indirectly, both on the side
of making an expression which refers to it, and for using an entity
passed in a variable. This is ugly.

> Thus, given all these namespaces, why should two of them, namely
> object and function bindings, be merged together?

Not only them; at least some others too.

> Because functions are objects? Is that a good enough reason?

Yes.

Why doesn't Lisp have a separate namespace for numbers? Or for files?
Or for arrays?

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <4415hoF1prsaqU1@individual.net>
Marcin 'Qrczak' Kowalczyk wrote:
> "Kaz Kylheku" <········@gmail.com> writes:
> 
>>Should you have only static scope, because dynamic scope is
>>introduces another symbol namespace?
> 
> Dynamic scope doesn't introduce another namespace.

In Common Lisp, it does:

(let ((x 'foo))
   (declare (special x))
   (print x)
   (let ((x 'bar))
     (print x)
     (locally (declare (special x))
       (print x))))

FOO
BAR
FOO

ISLISP's distinction between lexically and dynamically scoped variables 
makes this clearer.

> It can be expressed
> using static scope in the core and little syntactic sugar over variable
> references and assignments.

...but that's not necessarily a good implementation. There are other 
implementations that give you different / better performance 
characteristics. It's good that Common Lisp provides special variables 
as a language constructs because it allows vendors to implement it 
efficiently internally without programmers having to reinvent the wheel 
over and over again.

>>Should I not be able to define a class FOO and a function FOO at the
>>same time?
> 
> Should I not be able to write just FOO to refer to the function FOO,
> or class FOO? Having separate namespaces for first-class entities
> requires an extra syntax for passing them indirectly, both on the side
> of making an expression which refers to it, and for using an entity
> passed in a variable.

This is correct.

> This is ugly.

This is subjective. Lisp-2 has technical advantages (wrt decreased 
likelihood of accidental nameclashes). Lisp-1 seems to be only preferred 
for aesthetical reasons.

>>Thus, given all these namespaces, why should two of them, namely
>>object and function bindings, be merged together?
> 
> Not only them; at least some others too.
> 
>>Because functions are objects? Is that a good enough reason?
> 
> Yes.
> 
> Why doesn't Lisp have a separate namespace for numbers? Or for files?
> Or for arrays?

The car position in an s-expression has a special meaning that is 
different from the cdr positions anyway: The car position determines the 
meaning while the cdr positions don't. So there is already a "natural" 
difference between those two roles.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87irs4h2t5.fsf@qrnik.zagroda>
Pascal Costanza <··@p-cos.net> writes:

>> Dynamic scope doesn't introduce another namespace.
>
> In Common Lisp, it does:

Yes (sort of; I'm not sure whether this should be called a separate
namespace). I meant that it doesn't have to; that this is the way it
happened to be designed, because dynamic scoping was earlier, but an
alternative design unambiguously uses a single namespace.

> ...but that's not necessarily a good implementation. There are other
> implementations that give you different / better performance
> characteristics. It's good that Common Lisp provides special
> variables as a language constructs because it allows vendors to
> implement it efficiently internally without programmers having to
> reinvent the wheel over and over again.

This is orthogonal. I didn't mean to avoid special-casing it in the
compiler nor to avoid making it available by default. I meant to let
dynamic scope live on top of static scope: a dynamically scoped
variable has a lexically scoped point of definition which introduces
its name, and local rebinding is an operation performed on an existing
variable. I believe that it has the same potential for optimization.

> This is subjective. Lisp-2 has technical advantages (wrt decreased
> likelihood of accidental nameclashes). Lisp-1 seems to be only
> preferred for aesthetical reasons.

A decent namespace system and a hygienic macro system solve the
problem of name clashes better: they don't just decrease the
likelihood but make code completely robust wrt. some clashes.

> The car position in an s-expression has a special meaning that is
> different from the cdr positions anyway: The car position determines
> the meaning while the cdr positions don't. So there is already a
> "natural" difference between those two roles.

A function is not always immediately applied, and the thing to be
applied is not always a directly named function. The roles are
partially overlapping.


Pascal Bourguignon <····@mouse-potato.com> writes:

> Well, the alternative is to have one language-level name space,
> and to introduce user conventions such as:
>
> MACRONAME
> ClassName
> functioName
> variable_name
>
> What's uglier?

Common Lisp already uses a naming convention where an alternative
design would not need one: special variables.

I prefer when different things look different, rather than when they
must be disambiguated by the context.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <441dt0F1q0sjoU1@individual.net>
Marcin 'Qrczak' Kowalczyk wrote:

> A decent namespace system and a hygienic macro system solve the
> problem of name clashes better: they don't just decrease the
> likelihood but make code completely robust wrt. some clashes.

I had problems with nameclashes in Scheme, without using macros at all. 
There was no way to handle the nameclash at all, apart from renaming one 
of the variables manually.

This:

(let ((list '(1 2 3)))
   (list list))

...doesn't work in Scheme, but it does in Common Lisp. This is a toy 
example, but the problem I had was a similar one. I don't recall ever 
having such a problem in Common Lisp. It seems to be hard to accept for 
some people that nameclashes are completely unrelated to macro programming.

>>The car position in an s-expression has a special meaning that is
>>different from the cdr positions anyway: The car position determines
>>the meaning while the cdr positions don't. So there is already a
>>"natural" difference between those two roles.
> 
> A function is not always immediately applied, and the thing to be
> applied is not always a directly named function. The roles are
> partially overlapping.

Maybe, but that's not related to what I said. In the following Scheme 
code example, three x's play a different role than the remaining one:

(x x x x)

The first x determines what the code means, the others don't.

> Pascal Bourguignon <····@mouse-potato.com> writes:
> 
>>Well, the alternative is to have one language-level name space,
>>and to introduce user conventions such as:
>>
>>MACRONAME
>>ClassName
>>functioName
>>variable_name
>>
>>What's uglier?
> 
> Common Lisp already uses a naming convention where an alternative
> design would not need one: special variables.

Yes, ISLISP has solved this in a better way. There, you don't need the 
naming convention with the leading and trailing asterisks like in Common 
Lisp.

> I prefer when different things look different, rather than when they
> must be disambiguated by the context.

Again, in Scheme it is already the case that the context determines 
different meanings for variables.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <8764o4qs99.fsf@qrnik.zagroda>
Pascal Costanza <··@p-cos.net> writes:

> I had problems with nameclashes in Scheme, without using macros at
> all. There was no way to handle the nameclash at all, apart from
> renaming one of the variables manually.
>
> This:
>
> (let ((list '(1 2 3)))
>    (list list))

I prefer to name different things used in the same scope by different
names.

For my language I adopted a naming convention where capitalization
distinguishes global and local names. This solves roughly the same
amount of clashes as distinguishing function names from generic value
names, and at the same time doesn't need extra syntax for using
functions as first-class values.

> Maybe, but that's not related to what I said. In the following Scheme
> code example, three x's play a different role than the remaining one:
>
> (x x x x)
>
> The first x determines what the code means, the others don't.

No, they play the same role. In all places they denote the same
function.

You could as well say that in (setf (aref x i) i) the i's play
different roles. Well, in some sense they do, but it doesn't mean
that they should be interpreted in different namespaces; the roles
use the same meaning of the identifier, and the same entity can be
used as either the index or the value. Similarly for functions and
values.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Coby Beck
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <lBSCf.154264$km.145726@edtnps89>
"Marcin 'Qrczak' Kowalczyk" <······@knm.org.pl> wrote in message 
···················@qrnik.zagroda...
> Pascal Costanza <··@p-cos.net> writes:
>
>> I had problems with nameclashes in Scheme, without using macros at
>> all. There was no way to handle the nameclash at all, apart from
>> renaming one of the variables manually.
>>
>> This:
>>
>> (let ((list '(1 2 3)))
>>    (list list))
>
> I prefer to name different things used in the same scope by different
> names.

Fine.  That's your preference.  You think (funcall #'foo bar) is ugly. 
That's you opinion.  This whole debate is a matter of entirely subjective 
and personal opinion.

> For my language I adopted a naming convention where capitalization
> distinguishes global and local names. This solves roughly the same
> amount of clashes as distinguishing function names from generic value
> names, and at the same time doesn't need extra syntax for using
> functions as first-class values.
>
>> Maybe, but that's not related to what I said. In the following Scheme
>> code example, three x's play a different role than the remaining one:
>>
>> (x x x x)
>>
>> The first x determines what the code means, the others don't.
>
> No, they play the same role. In all places they denote the same
> function.

You are wrong, and your "explanation" is just a non-seqitur.  The first x in 
that list determines what will happen to the other three x's,  that all 
three x's represent the same object is non seqitur.  Not only that, but in 
both CL and Scheme the first x *must* represent a function object.  Sounds 
like a special case to me.

The function position *is* special even while a function object is *not* 
special.  Whichever one of those facts is more important to you as a guide 
to defining the language is a matter of personal opinion.

Everything else is just noise that has been made many times before.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87k6ckapxh.fsf@qrnik.zagroda>
"Coby Beck" <·····@mercury.bc.ca> writes:

> The first x in that list determines what will happen to the other
> three x's, that all three x's represent the same object is non
> seqitur. Not only that, but in both CL and Scheme the first x *must*
> represent a function object. Sounds like a special case to me.

That they are in some aspect "special" is not an argument for making
them special also wrt. the namespace.

You can argue that having a different namespace helps with avoiding
name clashes, allows to choose better looking names, etc. - fine.
But arguing that they need a different namespace because they are
already a special case is nonsense.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <442g8aF2cd2U1@individual.net>
Marcin 'Qrczak' Kowalczyk wrote:
> "Coby Beck" <·····@mercury.bc.ca> writes:
> 
>>The first x in that list determines what will happen to the other
>>three x's, that all three x's represent the same object is non
>>seqitur. Not only that, but in both CL and Scheme the first x *must*
>>represent a function object. Sounds like a special case to me.
> 
> That they are in some aspect "special" is not an argument for making
> them special also wrt. the namespace.
> 
> You can argue that having a different namespace helps with avoiding
> name clashes, allows to choose better looking names, etc. - fine.
> But arguing that they need a different namespace because they are
> already a special case is nonsense.

Noone argues that it must be like that, that there is no other choice - 
Scheme proves that a different design choice can be made.

But you have explicitly asked why there are no separate namespaces for 
numbers, for files or for arrays. That would be arbitrary and wouldn't 
really serve a purpose. The fact that the car position in an 
s-expression plays a special role is, however, a reason. You may not 
like it, but it is a reason nevertheless.

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: patro
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <drh1rs$449$1@atlantis.news.tpi.pl>
"Marcin 'Qrczak' Kowalczyk" <······@knm.org.pl> wrote:

> For my language I adopted a naming convention where capitalization
> distinguishes global and local names.

Why don't you adopt a convention of distinguishing names introduced in the
most inner scope from the others (for example by capitalizing the last
letter of a name) ?
From: Nicolas Neuss
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87vew4tbih.fsf@ortler.iwr.uni-heidelberg.de>
Pascal Costanza <··@p-cos.net> writes:

> This:
>
> (let ((list '(1 2 3)))
>   (list list))
>
> ...doesn't work in Scheme, but it does in Common Lisp. This is a toy
> example, but the problem I had was a similar one. I don't recall ever
> having such a problem in Common Lisp. It seems to be hard to accept for
> some people that nameclashes are completely unrelated to macro
> programming.

When I programmed in Scheme, I disliked most the problems arising with slot
accessors, e.g.

(let ((color (color object)))
  (when (eql color (color object2))
     ...))

would not work in Scheme (together with some CLOS-like system - I used
Guile's GOOPS at that time).

Nicolas.
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87irs4ttma.fsf@thalassa.informatimago.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
>> Should I not be able to define a class FOO and a function FOO at the
>> same time?
>
> Should I not be able to write just FOO to refer to the function FOO,
> or class FOO? Having separate namespaces for first-class entities
> requires an extra syntax for passing them indirectly, both on the side
> of making an expression which refers to it, and for using an entity
> passed in a variable. This is ugly.

Well, the alternative is to have one language-level name space,
and to introduce user conventions such as:

MACRONAME
ClassName
functioName
variable_name

What's uglier?


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.
From: Marcus Breiing
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <vxgdb89p115ai@breiing.com>
* Marcin 'Qrczak' Kowalczyk

> Should I not be able to write just FOO to refer to the function FOO,
> or class FOO? 

Actually, when you write FOO in Common Lisp, you're referring to a
symbol.

-- 
Marcus Breiing
From: Kenny Tilton
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1L9Cf.9388$SD.501@news-wrt-01.rdc-nyc.rr.com>
funkyj wrote:
> I've heard that CL macros are more poweful than Scheme macros.
> Assuming this is true, what is the simplest example illustrating this
> difference?

I would be fascinated to see this myself. I have heard of Scheme's 
alternative approach but never quite grokked it, possibly because it 
came in the middle of an intense debate between a couple of wizards.

kenny
From: Kaz Kylheku
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138312667.911464.223810@g43g2000cwa.googlegroups.com>
Kenny Tilton wrote:
> I would be fascinated to see this myself. I have heard of Scheme's
> alternative approach but never quite grokked it, possibly because it
> came in the middle of an intense debate between a couple of wizards.

Which of them lost more hitpoints in the transaction?
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43smdtF1p7kljU1@individual.net>
funkyj wrote:
> I've heard that CL macros are more poweful than Scheme macros.
> Assuming this is true, what is the simplest example illustrating this
> difference?

There is no simplest example that illustrates the differences. Among 
other things, there are several macro systems for Scheme with different 
approaches to implementing macros, so finding just one example is not an 
easy task.

An important difference between Scheme and Common Lisp macro systems is 
how variable capture is typically handled. In Common Lisp, someone who 
implements a macro has to take care of this himself. See 
http://www.paulgraham.com/onlisp.html for an extensive discussion how to 
do this in Common Lisp. This is an excellent book about macro 
programming in Common Lisp anyway...

Scheme macro systems tend to favor automatic hygiene, which means that 
variable capture is automatically taken care of by the macro system. The 
problem and one of the various macro systems is explained in 
ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-1049.pdf

There was a usenet posting (?) about the history of Scheme macro 
systems, but I don't seem to be able to find it at the moment. You can 
find more literature about Scheme macros at 
http://library.readscheme.org/page3.html

> another CL vs Scheme question:
> 
> What is the history behind CL having separate function and variable
> namespaces?

As far as I can tell, the fact that Common Lisp is a Lisp-2 is a 
historical accident.

> It seems to me that CL's 2 namespaces confers no particular advantage
> while adding complexity.  Is the CL 2 namespace approach merely an
> evolutionary artifact or does it confer some significant advantage over
> the 1 namespace approach that I have yet to perceive?

Common Lisp's preference for multiple namespaces seems to reduce the 
number of accidental nameclashes, including those that occur 
independently of macros, at least in my experience.

For example, it's a good exercise to see which of the four examples in 
the paper cited above cannot occur in a Lisp-2.

Sorry, but I don't think there is a shortcut to illustrating and 
especially understanding the differences. These topics have been 
discussed at length in the past, both in comp.lang.lisp and 
comp.lang.scheme, so you should find plenty of material by googling for it.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: ··········@yahoo.com
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138325071.269629.326570@g43g2000cwa.googlegroups.com>
> > What is the history behind CL having separate function and variable
> > namespaces?
>
> As far as I can tell, the fact that Common Lisp is a Lisp-2 is a
> historical accident.


I doubt it's merely an accident. Having the ability to use a symbol
as both a verb and a noun is a huge blessing. That is, being able
to write (foo foo). Also, lisp-2-ness is related to the structure of
lisp symbols, which are not just canonical strings or keywords.
Aside from a property list, a symbol has both a value cell and a
function cell. So you can do the following

(setf vec (make-array 5 :initial-contents '(10 20 30 40 50)))

The value cell of of vec contains

#(10 20 30 40 50)

Now set the function cell of vec...

[4]> (setf (symbol-function 'vec) (lambda (i) (aref vec i)))

#<FUNCTION :LAMBDA (I) (AREF VEC I)>

[5]> (vec 0)

10

[6]> (vec 3)

40

Now vec can aref itself. Is this possible in a lisp-1 or with
scheme symbols? 

krung
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138343928.301096.30280@g14g2000cwa.googlegroups.com>
··········@yahoo.com wrote:

> Now vec can aref itself. Is this possible in a lisp-1 or with
> scheme symbols? 

Hmm, that was interesting.

Thanks,
  --jfc
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43u2t1F1phsliU1@individual.net>
··········@yahoo.com wrote:
>>>What is the history behind CL having separate function and variable
>>>namespaces?
>>
>>As far as I can tell, the fact that Common Lisp is a Lisp-2 is a
>>historical accident.
> 
> I doubt it's merely an accident. Having the ability to use a symbol
> as both a verb and a noun is a huge blessing.

I totally agree that this is a good thing - it's one of the main reasons 
why I stick to Common Lisp and don't like using Scheme.

However, when you read about the history of the first Lisp papers and 
implementations, it doesn't seem to me that anyone has thought this 
through at that point in time. (Several other elements of Lisp that have 
proven to be very powerful were not considered valuable back in those 
days, including for example the advantages of s-expressions over 
m-expressions.)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Thomas F. Burdick
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <xcvvew6vvq9.fsf@conquest.OCF.Berkeley.EDU>
Pascal Costanza <··@p-cos.net> writes:

> ··········@yahoo.com wrote:
> >>>What is the history behind CL having separate function and variable
> >>>namespaces?
> >>
> >>As far as I can tell, the fact that Common Lisp is a Lisp-2 is a
> >>historical accident.
> > I doubt it's merely an accident. Having the ability to use a symbol
> > as both a verb and a noun is a huge blessing.
> 
> I totally agree that this is a good thing - it's one of the main
> reasons why I stick to Common Lisp and don't like using Scheme.
> 
> However, when you read about the history of the first Lisp papers and
> implementations, it doesn't seem to me that anyone has thought this
> through at that point in time. (Several other elements of Lisp that
> have proven to be very powerful were not considered valuable back in
> those days, including for example the advantages of s-expressions over
> m-expressions.)

Sure, the fact that LISP 1.5 was a Lisp-2 is likely an accident.  But
by the time CL was designed, it was a conscious choice.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pascal Bourguignon
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87y812ufck.fsf@thalassa.informatimago.com>
···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Pascal Costanza <··@p-cos.net> writes:
>
>> ··········@yahoo.com wrote:
>> >>>What is the history behind CL having separate function and variable
>> >>>namespaces?
>> >>
>> >>As far as I can tell, the fact that Common Lisp is a Lisp-2 is a
>> >>historical accident.
>> > I doubt it's merely an accident. Having the ability to use a symbol
>> > as both a verb and a noun is a huge blessing.
>> 
>> I totally agree that this is a good thing - it's one of the main
>> reasons why I stick to Common Lisp and don't like using Scheme.
>> 
>> However, when you read about the history of the first Lisp papers and
>> implementations, it doesn't seem to me that anyone has thought this
>> through at that point in time. (Several other elements of Lisp that
>> have proven to be very powerful were not considered valuable back in
>> those days, including for example the advantages of s-expressions over
>> m-expressions.)
>
> Sure, the fact that LISP 1.5 was a Lisp-2 is likely an accident.  But
> by the time CL was designed, it was a conscious choice.

Only the people who designed it could really say.

I note that symbols had only one slot: their plist.  Both the name,
the function and the value of a symbol were put on its property list
along with any other property.  Looks much more like lisp-n than
lisp-2 :-)



For example here is the symbol T:

HH63           -1,,-*-1           T                                     GPLA0235
               PNAME,,-*-1                                              GPLA0236
               -*-1,,-*-3         T                                     GPLA0237
               -*-1                                                     GPLA0238
       OCT     637777777777                                             GPLA0239
               APVAL,,-*-1                                              GPLA0240
               -*-1                                                     GPLA0241
               1                                                        GPLA0242


( -1 PNAME ("T") APVAL (1) )


and here is the symbols PAIR:

)080           -1,,-*-1                                                 GPLI0871
               SUBR,,-*-1                                               GPLI0872
               -*-1,,-*-2                                               GPLI0873
       TXL     PAIR,,2                                                  GPLI0874
               PNAME,,-*-1                                              GPLI0875
               -*-1               PAIR                                  GPLI0876
               -*-1                                                     GPLI0877
       OCT     472131517777                                             GPLI0878


( -1 SUBR ( #.(CALL PAIR 2) ) PNAME ("PAIR") )



and the special operator FUNCTION:

)045           -1,,-*-1                                                 GPLI0534
               FSUBR,,-*-1                                              GPLI0535
               -*-1,,-*-2                                               GPLI0536
       TXL     $LAMP,,0                                                 GPLI0537
               PNAME,,-*-1                                              GPLI0538
               -*-1               FUNCTION                              GPLI0539
               -*-1,,-*-2                                               GPLI0540
       OCT     266445236331                                             GPLI0541
               -*-1                                                     GPLI0542
       OCT     464577777777                                             GPLI0543

( -1 FSUBR ( #.(CALL $LAMP 0) ) PNAME ("FUNCTI" "ON") )

Strings were represented as lists of 6-character words.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live.
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43uecnF1ph1h4U1@individual.net>
Pascal Bourguignon wrote:
> ···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> 
>>Pascal Costanza <··@p-cos.net> writes:
>>
>>>··········@yahoo.com wrote:
>>>
>>>>>>What is the history behind CL having separate function and variable
>>>>>>namespaces?
>>>>>
>>>>>As far as I can tell, the fact that Common Lisp is a Lisp-2 is a
>>>>>historical accident.
>>>>
>>>>I doubt it's merely an accident. Having the ability to use a symbol
>>>>as both a verb and a noun is a huge blessing.
>>>
>>>I totally agree that this is a good thing - it's one of the main
>>>reasons why I stick to Common Lisp and don't like using Scheme.
>>>
>>>However, when you read about the history of the first Lisp papers and
>>>implementations, it doesn't seem to me that anyone has thought this
>>>through at that point in time. (Several other elements of Lisp that
>>>have proven to be very powerful were not considered valuable back in
>>>those days, including for example the advantages of s-expressions over
>>>m-expressions.)
>>
>>Sure, the fact that LISP 1.5 was a Lisp-2 is likely an accident.  But
>>by the time CL was designed, it was a conscious choice.
> 
> Only the people who designed it could really say.

The paper http://www.nhplace.com/kent/Papers/Technical-Issues.html is a 
clear indication that it was indeed a conscious decision to stick with 
Lisp-2 during CL standardization.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Adrian Kubala
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <slrndtl4do.t3k.adrian-news@sixfingeredman.net>
On 2006-01-27, ··········@yahoo.com <··········@yahoo.com> wrote:
> (setf vec (make-array 5 :initial-contents '(10 20 30 40 50)))
>
> The value cell of of vec contains
>
> #(10 20 30 40 50)
>
> Now set the function cell of vec...
>
> [4]> (setf (symbol-function 'vec) (lambda (i) (aref vec i)))
>
> #<FUNCTION :LAMBDA (I) (AREF VEC I)>
>
> [5]> (vec 0)
>
> 10

[6]> ((lambda (x) (x 0)) vec)

*** - EVAL: undefined function X

Hm, not quite as useful as one might think, is it? What we really want
for this abstraction is a way to override "apply" for a VALUE, not a
symbol; like you can do in C++ by overriding operator() or in Python by
overriding __call__.
From: jayessay
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m3zmlh8g4r.fsf@rigel.goldenthreadtech.com>
Adrian Kubala <···········@sixfingeredman.net> writes:

> On 2006-01-27, ··········@yahoo.com <··········@yahoo.com> wrote:
> > (setf vec (make-array 5 :initial-contents '(10 20 30 40 50)))
> >
> > The value cell of of vec contains
> >
> > #(10 20 30 40 50)
> >
> > Now set the function cell of vec...
> >
> > [4]> (setf (symbol-function 'vec) (lambda (i) (aref vec i)))
> >
> > #<FUNCTION :LAMBDA (I) (AREF VEC I)>
> >
> > [5]> (vec 0)
> >
> > 10
> 
> [6]> ((lambda (x) (x 0)) vec)
> 
> *** - EVAL: undefined function X
> 
> Hm, not quite as useful as one might think, is it? 

You appear to simply be misunderstanding the namespace issue - in the
face of some of the very evidence that is meant to illuminate it.


> What we really want for this abstraction is a way to override
> "apply" for a VALUE, not a symbol;

I would say that what you really want is to simply understand and use
the constructions as they are intended:

((lambda (x) (funcall x 0)) (symbol-function 'vec))

==> 10

You're next comment will probably be something like 'that's
ugly/verbose/...', not realizing that you can easily "fix" that as
well (hint: macros).


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Adrian Kubala
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <slrndtq94n.4u0.adrian-news@sixfingeredman.net>
On 2006-01-27, jayessay <······@foo.com> wrote:
> ((lambda (x) (funcall x 0)) (symbol-function 'vec))
> You're next comment will probably be something like 'that's
> ugly/verbose/...', not realizing that you can easily "fix" that as
> well (hint: macros).

No, you need to be able to have both these work:
((lambda (x) (x 0)) vec)
((lambda (x) (aref x 0)) vec)

That's the whole point of the original trick; being able to use a vector
as either a function OR a vector. Of course, it can't work, because the
dual-meaning is tied to the symbol, not the value.
From: jayessay
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m3lkwv7xvf.fsf@rigel.goldenthreadtech.com>
Adrian Kubala <···········@sixfingeredman.net> writes:

> On 2006-01-27, jayessay <······@foo.com> wrote:
> > ((lambda (x) (funcall x 0)) (symbol-function 'vec))
> > You're next comment will probably be something like 'that's
> > ugly/verbose/...', not realizing that you can easily "fix" that as
> > well (hint: macros).
> 
> No, you need to be able to have both these work:
> ((lambda (x) (x 0)) vec)
> ((lambda (x) (aref x 0)) vec)
> 
> That's the whole point of the original trick; being able to use a vector
> as either a function OR a vector. Of course, it can't work, because the
> dual-meaning is tied to the symbol, not the value.

No, the dual _meanings_ come from different _usage patterns_.  These,
of course, can be distinguished.  If you say you don't want to make
such distinction, then you really do not want what you said you want
above.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: rydis (Martin Rydstr|m) @CD.Chalmers.SE
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <w4cfyn18jd3.fsf@boris.cd.chalmers.se>
Adrian Kubala <···········@sixfingeredman.net> writes:
> On 2006-01-27, jayessay <······@foo.com> wrote:
> > ((lambda (x) (funcall x 0)) (symbol-function 'vec))
> > You're next comment will probably be something like 'that's
> > ugly/verbose/...', not realizing that you can easily "fix" that as
> > well (hint: macros).
> 
> No, you need to be able to have both these work:
> ((lambda (x) (x 0)) vec)
> ((lambda (x) (aref x 0)) vec)
> 
> That's the whole point of the original trick; being able to use a vector
> as either a function OR a vector. Of course, it can't work, because the
> dual-meaning is tied to the symbol, not the value.

Arrays were funcallable with their subscripts as arguments in MacLisp.
That didn't propagate to CL. Why is left as a fact-finding exercise.

',mr

-- 
[Emacs] is written in Lisp, which is the only computer language that is
beautiful.  -- Neal Stephenson, _In the Beginning was the Command Line_
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43vj7mF1pm6grU1@individual.net>
Adrian Kubala wrote:
> On 2006-01-27, ··········@yahoo.com <··········@yahoo.com> wrote:
> 
>>(setf vec (make-array 5 :initial-contents '(10 20 30 40 50)))
>>
>>The value cell of of vec contains
>>
>>#(10 20 30 40 50)
>>
>>Now set the function cell of vec...
>>
>>[4]> (setf (symbol-function 'vec) (lambda (i) (aref vec i)))
>>
>>#<FUNCTION :LAMBDA (I) (AREF VEC I)>
>>
>>[5]> (vec 0)
>>
>>10
> 
> 
> [6]> ((lambda (x) (x 0)) vec)
> 
> *** - EVAL: undefined function X
> 
> Hm, not quite as useful as one might think, is it? What we really want
> for this abstraction is a way to override "apply" for a VALUE, not a
> symbol; like you can do in C++ by overriding operator() or in Python by
> overriding __call__.

(shadow 'lambda)

(defmacro lambda ((&rest args) &body body)
   `(cl:lambda (,@args)
      (flet ,(loop for arg in args
                   collect `(,arg (&rest args)
                              (declare (dynamic-extent args))
                              (apply ,arg args)))
        ,@body)))

 > (funcall (lambda (x) (x 'foo)) #'print)

FOO

Not quite there yet, but we're getting closer... ;)


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: John Thingstad
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <op.s33aajumpqzri1@mjolner.upc.no>
>
> (shadow 'lambda)
>
> (defmacro lambda ((&rest args) &body body)
>    `(cl:lambda (,@args)
>       (flet ,(loop for arg in args
>                    collect `(,arg (&rest args)
>                               (declare (dynamic-extent args))
>                               (apply ,arg args)))
>         ,@body)))
>
>  > (funcall (lambda (x) (x 'foo)) #'print)
>
> FOO
>
> Not quite there yet, but we're getting closer... ;)
>
>
> Pascal
>

As in CloserL..
A bit to hard-core for my taste..

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <87u0bolhoi.fsf@qrnik.zagroda>
··········@yahoo.com writes:

> Aside from a property list, a symbol has both a value cell and a
> function cell. So you can do the following

But this is pretty useless, as such value-function combination is not
first-class: you can't pass it as a parameter while keeping the syntax
of using it.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <4415jkF1nbe65U1@individual.net>
Marcin 'Qrczak' Kowalczyk wrote:
> ··········@yahoo.com writes:
> 
>>Aside from a property list, a symbol has both a value cell and a
>>function cell. So you can do the following
> 
> But this is pretty useless, as such value-function combination is not
> first-class: you can't pass it as a parameter while keeping the syntax
> of using it.

You can, but this requires more work.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Kenny Tilton
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <54aCf.9389$SD.5195@news-wrt-01.rdc-nyc.rr.com>
Pascal Costanza wrote:
> funkyj wrote:
> 
>> I've heard that CL macros are more poweful than Scheme macros.
>> Assuming this is true, what is the simplest example illustrating this
>> difference?
> 
....

> Scheme macro systems tend to favor automatic hygiene, which means that 
> variable capture is automatically taken care of by the macro system. The 
> problem and one of the various macro systems is explained in 
> ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-1049.pdf
> 
> There was a usenet posting (?) about the history of Scheme macro 
> systems, but I don't seem to be able to find it at the moment. You can 
> find more literature about Scheme macros at 
> http://library.readscheme.org/page3.html

What if you /want/ wot capture a variable? I sometimes have cooperating 
macros, an outer one setting up some context binding it to a certain 
variable expected by inner ones (valid only in the body of the outer).

kt
From: Pascal Costanza
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43t1m4F1p0dpqU1@individual.net>
Kenny Tilton wrote:
> Pascal Costanza wrote:
> 
>> funkyj wrote:
>>
>>> I've heard that CL macros are more poweful than Scheme macros.
>>> Assuming this is true, what is the simplest example illustrating this
>>> difference?
>>
>>
> ....
> 
>> Scheme macro systems tend to favor automatic hygiene, which means that 
>> variable capture is automatically taken care of by the macro system. 
>> The problem and one of the various macro systems is explained in 
>> ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-1049.pdf
>>
>> There was a usenet posting (?) about the history of Scheme macro 
>> systems, but I don't seem to be able to find it at the moment. You can 
>> find more literature about Scheme macros at 
>> http://library.readscheme.org/page3.html
> 
> What if you /want/ wot capture a variable? I sometimes have cooperating 
> macros, an outer one setting up some context binding it to a certain 
> variable expected by inner ones (valid only in the body of the outer).

AFAICT, most macro systems for Scheme allow you to express this (except 
for R5RS macros). It's just not the default. In Common Lisp, you have to 
work for keeping macros hygienic, in Scheme you have to work for 
breaking hygiene.


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43d948e4$0$38696$edfadb0f@dread12.news.tele.dk>
funkyj wrote:
> I've heard that CL macros are more poweful than Scheme macros.

Things aren't black and white.

If "Scheme macros" means "macros as in R5RS Scheme" then
in a practical sense the statement is correct. When R5RS
was written there were a lot of research on macros going
on, and no "winner" had appeared, so they "settled" on a
subset they could agree upon.

In a real implementation you'll find that they use
more powerful macros to implement the R5RS ones. There
still isn't one "winner", but variants of the syntax-case
system is wide spread - and that is just as powerful as
CL macros.

-- 
Jens Axel S�gaard
From: funkyj
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138319806.087228.254470@g14g2000cwa.googlegroups.com>
Jens Axel Søgaard wrote:
> funkyj wrote:
> > I've heard that CL macros are more poweful than Scheme macros.
>
> Things aren't black and white.
>
> If "Scheme macros" means "macros as in R5RS Scheme" then
> in a practical sense the statement is correct. When R5RS
> was written there were a lot of research on macros going
> on, and no "winner" had appeared, so they "settled" on a
> subset they could agree upon.

I meant to ask the "macros as in R5RS" question.

> In a real implementation you'll find that they use
> more powerful macros to implement the R5RS ones.

Hmmmm.  OK.

> There
> still isn't one "winner", but variants of the syntax-case
> system is wide spread - and that is just as powerful as
> CL macros.

Reasoning from "absence of corresponding CL anecdote" I'm guessing CL
macros are powerful enough that CL implementors do not implement them
in terms of an even more power but non-standard macro systems?

  --jfc
From: Peter Seibel
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <m2oe1yijhj.fsf@gigamonkeys.com>
"funkyj" <······@gmail.com> writes:

> Reasoning from "absence of corresponding CL anecdote" I'm guessing
> CL macros are powerful enough that CL implementors do not implement
> them in terms of an even more power but non-standard macro systems?

Indeed, it seems one of the great virtues of CL style macros is that
they're pretty trivial to implement. Check out:

  <http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html>

to see how trivial. (That chapter is about building an embedded HTML
generation library in Common Lisp but it include the ability to write
HTML generation macros which work, for the HTML generation language
much like Common Lisp macros do for Common Lisp.)

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43d9662e$0$38679$edfadb0f@dread12.news.tele.dk>
funkyj wrote:

> Reasoning from "absence of corresponding CL anecdote" I'm guessing CL
> macros are powerful enough that CL implementors do not implement them
> in terms of an even more power but non-standard macro systems?

Yes - just keep in mind, that it was intentionally that the power of 
R5RS was restricted.

Also, the syntax-case system is a defacto standard (in my view, some
Schemers might disagree).

-- 
Jens Axel S�gaard
From: Christophe Rhodes
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <sqy812sk5n.fsf@cam.ac.uk>
Jens Axel Søgaard <······@soegaard.net> writes:

> funkyj wrote:
>> I've heard that CL macros are more poweful than Scheme macros.
>
> Things aren't black and white.
>
> If "Scheme macros" means "macros as in R5RS Scheme" then
> in a practical sense the statement is correct.

I believe that Al* Petrofsky over on comp.lang.scheme would dispute
this.  (Of course, then an argument over the meaning of the word
"practical" would ensue).

Christophe
From: =?UTF-8?B?SmVucyBBeGVsIFPDuGdhYXJk?=
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43d94d2c$0$38677$edfadb0f@dread12.news.tele.dk>
Christophe Rhodes wrote:
> Jens Axel Søgaard <······@soegaard.net> writes:

> I believe that Al* Petrofsky over on comp.lang.scheme would dispute
> this.  (Of course, then an argument over the meaning of the word
> "practical" would ensue).

It was coincendental I chose that word ;-)

-- 
Jens Axel Søgaard
From: Kenny Tilton
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1XcCf.7428$cj3.916@news-wrt-01.rdc-nyc.rr.com>
Christophe Rhodes wrote:
> Jens Axel Søgaard <······@soegaard.net> writes:
> 
> 
>>funkyj wrote:
>>
>>>I've heard that CL macros are more poweful than Scheme macros.
>>
>>Things aren't black and white.
>>
>>If "Scheme macros" means "macros as in R5RS Scheme" then
>>in a practical sense the statement is correct.
> 
> 
> I believe that Al* Petrofsky over on comp.lang.scheme would dispute
> this.  (Of course, then an argument over the meaning of the word
> "practical" would ensue).

Which is why actual examples would help. Allows everyone to apply their 
own mileage to "practical".

It occurred to me, though, that the OP asked for the simplest example 
that would illustrate the difference. That is a good idea, but I would 
also like to see how the Scheme macro scales to a realistic example.

kt
From: =?UTF-8?B?SmVucyBBeGVsIFPDuGdhYXJk?=
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43d96557$0$38679$edfadb0f@dread12.news.tele.dk>
Kenny Tilton wrote:
> Christophe Rhodes wrote:

>> I believe that Al* Petrofsky over on comp.lang.scheme would dispute
>> this.  (Of course, then an argument over the meaning of the word
>> "practical" would ensue).
> 
> Which is why actual examples would help. Allows everyone to apply their 
> own mileage to "practical".

Actual examples of things, which are not "practical"? Take
a look at Oleg's pages on macros:

     <http://okmij.org/ftp/Scheme/macros.html>

If it weren't for Al* and Oleg, I would have written "impossible"
in stead of "not practical".

> It occurred to me, though, that the OP asked for the simplest example 
> that would illustrate the difference. 

R5RS-macros can't do arbitrary computations, so it is hard to
produce new indentifiers - which makes it impractical
to write e.g. define-structure as a R5RS macro.

     <http://okmij.org/ftp/Scheme/define-struct.html>

> That is a good idea, but I would 
> also like to see how the Scheme macro scales to a realistic example.

Realistic examples of the use of R5RS macros or if a
"real" Scheme macro system?

To see what can be implemented with R5RS macros, look at the
"loop" macros in srfi-42. The reference implementation uses
nothing but syntax-rules macros.

     <http://srfi.schemers.org/srfi-42/srfi-42.html>

If you mean reasonable macros, take a look at:

R. Kent Dybvig. "Writing Hygenic Macros in Scheme with Syntax-Case"
<ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/pubs/iucstr356.ps.gz>

Real examples of the use of syntax-case can be found in, say,
the source of PLT Scheme.

-- 
Jens Axel Søgaard
From: Wade Humeniuk
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <KUdCf.148264$km.146796@edtnps89>
funkyj wrote:
> I've heard that CL macros are more poweful than Scheme macros.
> Assuming this is true, what is the simplest example illustrating this
> difference?
> 

Sure, how about...?

(defmacro random-closure (&rest random-expression)
   (compile nil `(lambda () ,@random-expression)))

(defun +random-amount (n)
   (+ n (funcall (random-closure (random 1024)))))


CL-USER 6 > (random-closure)
#<function 9 206786D2>

CL-USER 7 > (+random-amount 12)
745

CL-USER 8 >

Wade

> another CL vs Scheme question:
> 
> What is the history behind CL having separate function and variable
> namespaces?
> 
> It seems to me that CL's 2 namespaces confers no particular advantage
> while adding complexity.  Is the CL 2 namespace approach merely an
> evolutionary artifact or does it confer some significant advantage over
> the 1 namespace approach that I have yet to perceive?
> 
> Please direct all religious follow up discussions to alt.flame
> 
> Regards,
>   --jfc
> 
From: ··········@gmail.com
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138340732.264304.26520@z14g2000cwz.googlegroups.com>
Wade Humeniuk wrote:
> funkyj wrote:
> > I've heard that CL macros are more poweful than Scheme macros.
> > Assuming this is true, what is the simplest example illustrating this
> > difference?
> >
>
> Sure, how about...?
>
> (defmacro random-closure (&rest random-expression)
>    (compile nil `(lambda () ,@random-expression)))
>
> (defun +random-amount (n)
>    (+ n (funcall (random-closure (random 1024)))))
>
>
> CL-USER 6 > (random-closure)
> #<function 9 206786D2>
>
> CL-USER 7 > (+random-amount 12)
> 745

???

(define-syntax random-closure
  (syntax-rules ()
    ((_ . random-expression)
     (lambda () . random-expression))))

(define (+random-amount n)
  (+ n ((random-closure (random 1024)))))

Welcome to MzScheme version 209, Copyright (c) 2004 PLT Scheme, Inc.
> > > (+random-amount 12)
416
> (+random-amount 12)
308

There's not really much of a difference in this case.
From: Jens Axel Søgaard
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <43d9e08a$0$38672$edfadb0f@dread12.news.tele.dk>
··········@gmail.com wrote:
> Wade Humeniuk wrote:
> 
>>funkyj wrote:
>>
>>>I've heard that CL macros are more poweful than Scheme macros.
>>>Assuming this is true, what is the simplest example illustrating this
>>>difference?
>>>
>>
>>Sure, how about...?
>>
>>(defmacro random-closure (&rest random-expression)
>>   (compile nil `(lambda () ,@random-expression)))
>>
>>(defun +random-amount (n)
>>   (+ n (funcall (random-closure (random 1024)))))

> (define-syntax random-closure
>   (syntax-rules ()
>     ((_ . random-expression)
>      (lambda () . random-expression))))
> 
> (define (+random-amount n)
>   (+ n ((random-closure (random 1024)))))

> There's not really much of a difference in this case.

The hard part is the (compile nil ...).

Wade's macro calls a function to calculate the result
of the expansion. It is not possible to call an arbitrary
function using syntax-rules. In a syntax-case
system there is no problems:

(define-syntax (random-closure stx)
   (syntax-case stx ()
     [(random-closure random-expression ...)
      #`#,(eval (compile
                 #'(lambda () random-expression ...)))]))

(define (+random-amount n)
   (+ n ((random-closure (random 1024)))))

Here #' is syntax-quote, #` is syntax-quasiquote
and #, is syntax-unquote. The construct syntax-objects
containing (among other things) source location
information.

A syntax-case macro must return a syntax-object
(at least in PLT Scheme), so #`#,(eval ...) is an idiom
that makes sure the output of calling eval will be
converted into a syntax-object is returned.

-- 
Jens Axel S�gaard



-- 
Jens Axel S�gaard
From: ··········@gmail.com
Subject: Re: CL vs scheme macros, namespaces.
Date: 
Message-ID: <1138372644.691485.218980@g44g2000cwa.googlegroups.com>
Jens Axel Søgaard wrote:
> The hard part is the (compile nil ...).
<snip>

Oops!  Thanks for clearing this up.