From: Pillsy
Subject: More questions about exported symbols and general style.
Date: 
Message-ID: <1167237130.595431.88780@i12g2000cwa.googlegroups.com>
Well, two questions about exporting symbols, really. Say I want to set
up bindings to captured variables (like IT in anaphoric macros) in
packages that I'll be using. Do I want to just export IT and friends,
or should I walk through the code and replace them with gensyms or
something?

Also, I've found I've gotten in the habit of naming captured variables
like IT names that begin with dollar signs, i.e., $IT, so they stand
out a bit. Bad, good or indifferent idea?

Cheers,
Pillsy

From: Zach Beane
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <m364bx6z8e.fsf@unnamed.xach.com>
"Pillsy" <·········@gmail.com> writes:

> Well, two questions about exporting symbols, really. Say I want to set
> up bindings to captured variables (like IT in anaphoric macros) in
> packages that I'll be using. Do I want to just export IT and friends,
> or should I walk through the code and replace them with gensyms or
> something?

This is a bit of a tangent, but: don't write anaphoric macros. Making
names magically spring into existence without visible bindings is not
very Lispy.

When bindings are explicit, you don't have to worry about exporting
IT; the user can just use a symbol of their choosing. Plus, it nests
properly.

Zach
From: Pillsy
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1167241491.665594.20310@n51g2000cwc.googlegroups.com>
Zach Beane wrote:

> "Pillsy" <·········@gmail.com> writes:

> > Well, two questions about exporting symbols, really. Say I want to set
> > up bindings to captured variables (like IT in anaphoric macros) in
> > packages that I'll be using. Do I want to just export IT and friends,
> > or should I walk through the code and replace them with gensyms or
> > something?

> This is a bit of a tangent, but: don't write anaphoric macros. Making
> names magically spring into existence without visible bindings is not
> very Lispy.

I have considered this argument. I almost never use AIF, ACOND and the
like, but I do have various function-creating macros inspired by /On
Lisp/, like

(fn (+ $1 $2)) => (lambda ($1 $2) (+ $1 $2))

that I find more expressive (as well as more concise) than more
explicit alternatives. Besides, adding not-so-Lispy bits to Lisp is
pretty Lispy, what with FORMAT and LOOP. :^D

> When bindings are explicit, you don't have to worry about exporting
> IT; the user can just use a symbol of their choosing. Plus, it nests properly.

Upside: yes. Downside: they *have* to do that choosing, and since most
of my reliance on anaphora and such is in macros that make anonymous
functions, having visually weird magical bindings makes it easy to see
at a glance which variables are being closed over.

Cheers,
Pillsy
From: Bill Atkins
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <m2ejqljiaf.fsf@bertrand.local>
"Pillsy" <·········@gmail.com> writes:

> I have considered this argument. I almost never use AIF, ACOND and the
> like, but I do have various function-creating macros inspired by /On
> Lisp/, like
>
> (fn (+ $1 $2)) => (lambda ($1 $2) (+ $1 $2))

Ewww.

> Upside: yes. Downside: they *have* to do that choosing, and since most
> of my reliance on anaphora and such is in macros that make anonymous
> functions, having visually weird magical bindings makes it easy to see
> at a glance which variables are being closed over.

Personally, I prefer macros that bind to explicit variables:

  (when-let (message (read-next-message *the-connection*))
    (format t "~&Got message: ~S" message))

You can define a whole suite of these: IF-LET, COND-LET, etc. (or
BWHEN, BLET, BCOND).  They aren't much longer than their A*
equivalents and you get to avoid all the sticky side effects of using
anaphoric macros.
From: Pillsy
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1167246781.216606.8840@i12g2000cwa.googlegroups.com>
Bill Atkins wrote:

> "Pillsy" <·········@gmail.com> writes:

> > I have considered this argument. I almost never use AIF, ACOND and the
> > like, but I do have various function-creating macros inspired by /On
> > Lisp/, like

> > (fn (+ $1 $2)) => (lambda ($1 $2) (+ $1 $2))

> Ewww.

I had no idea people would hate that so much. I guess I know now why I
don't see more of it. :^)

Anonymous and even nonymous functions in other languages often work
this way. It was a pretty conscious imitation of what I like about
Mathematica's anonymous function syntax.

> > Upside: yes. Downside: they *have* to do that choosing, and since most
> > of my reliance on anaphora and such is in macros that make anonymous
> > functions, having visually weird magical bindings makes it easy to see
> > at a glance which variables are being closed over.

> Personally, I prefer macros that bind to explicit variables:

>   (when-let (message (read-next-message *the-connection*))
>     (format t "~&Got message: ~S" message))

> You can define a whole suite of these: IF-LET, COND-LET, etc. (or
> BWHEN, BLET, BCOND).  They aren't much longer than their A*
> equivalents and you get to avoid all the sticky side effects of using
> anaphoric macros.

I do like that better than the AIF, et c., so I may well *yoink* it for
myself. Still, it's tough to resist the terseness for anonymous
function declaration....

Cheers, 
Pillsy
From: Bill Atkins
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <m2k60d6ott.fsf@bertrand.local>
"Pillsy" <·········@gmail.com> writes:

> Bill Atkins wrote:
>
>> "Pillsy" <·········@gmail.com> writes:
>
>> > I have considered this argument. I almost never use AIF, ACOND and the
>> > like, but I do have various function-creating macros inspired by /On
>> > Lisp/, like
>
>> > (fn (+ $1 $2)) => (lambda ($1 $2) (+ $1 $2))
>
>> Ewww.
>
> I had no idea people would hate that so much. I guess I know now why I
> don't see more of it. :^)

For playing around at the REPL, that's a pretty useful macro, but I
would get a little uncomfortable if I saw that in actual source code.
YMMV, I guess.
From: Ken Tilton
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <YwKlh.623$Zf4.226@newsfe08.lga>
Zach Beane wrote:
> "Pillsy" <·········@gmail.com> writes:
> 
> 
>>Well, two questions about exporting symbols, really. Say I want to set
>>up bindings to captured variables (like IT in anaphoric macros) in
>>packages that I'll be using. Do I want to just export IT and friends,
>>or should I walk through the code and replace them with gensyms or
>>something?
> 
> 
> This is a bit of a tangent, but: don't write anaphoric macros. Making
> names magically spring into existence without visible bindings is not
> very Lispy.

Damn! Now I have to stop using special variables and symbol-macros?!!

OTOH, yes, i can see how using 'self' or 'this' to refer to 
the-instance-at-hand would be totally dumbfounding to the reader...

Thank God the authors of LOOP never got so unlispy as to allow "collect 
it"!!!

The point being that tightly-constrained stuff such as the above 
counterexamples are thoroughly unmagical and concomitantly readable.

(the bigger problem being anyone daft enought to nest anaphors and want 
some outer binding of it to hold.)

kt


-- 
The Dalai Lama gets the same crap all the time.
   -- Kenny Tilton on c.l.l when accused of immodesty
From: ·······@gmx.net
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1167580389.361624.141980@k21g2000cwa.googlegroups.com>
Ken Tilton schrieb:
>
> Damn! Now I have to stop using special variables and symbol-macros?!!
>
> OTOH, yes, i can see how using 'self' or 'this' to refer to
> the-instance-at-hand would be totally dumbfounding to the reader...
>
> Thank God the authors of LOOP never got so unlispy as to allow "collect
> it"!!!
>
> The point being that tightly-constrained stuff such as the above
> counterexamples are thoroughly unmagical and concomitantly readable.
>
> (the bigger problem being anyone daft enought to nest anaphors and want
> some outer binding of it to hold.)
> 

Well, how about rebinding those to *it **it and ***it ?
From: Pascal Costanza
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <4vq7sdF1d71vqU1@mid.individual.net>
Ken Tilton wrote:
> 
> Zach Beane wrote:
>> "Pillsy" <·········@gmail.com> writes:
>>
>>
>>> Well, two questions about exporting symbols, really. Say I want to set
>>> up bindings to captured variables (like IT in anaphoric macros) in
>>> packages that I'll be using. Do I want to just export IT and friends,
>>> or should I walk through the code and replace them with gensyms or
>>> something?
>>
>> This is a bit of a tangent, but: don't write anaphoric macros. Making
>> names magically spring into existence without visible bindings is not
>> very Lispy.
> 
> Damn! Now I have to stop using special variables and symbol-macros?!!

Special variables and symbol macros don't have that problem.

Try again... ;)

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ken Tilton
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <aBTlh.150$IQ3.81@newsfe10.lga>
Pascal Costanza wrote:
> Ken Tilton wrote:
> 
>>
>> Zach Beane wrote:
>>
>>> "Pillsy" <·········@gmail.com> writes:
>>>
>>>
>>>> Well, two questions about exporting symbols, really. Say I want to set
>>>> up bindings to captured variables (like IT in anaphoric macros) in
>>>> packages that I'll be using. Do I want to just export IT and friends,
>>>> or should I walk through the code and replace them with gensyms or
>>>> something?
>>>
>>>
>>> This is a bit of a tangent, but: don't write anaphoric macros. Making
>>> names magically spring into existence without visible bindings is not
>>> very Lispy.
>>
>>
>> Damn! Now I have to stop using special variables and symbol-macros?!!
> 
> 
> Special variables and symbol macros don't have that problem.

Classic rongarretesque unexplained rejoinder trying to bait someone into 
godknowswhat.

> 
> Try again... ;)

Don't try again; I was right the first time.

kt

-- 
The Dalai Lama gets the same crap all the time.
   -- Kenny Tilton on c.l.l when accused of immodesty
From: Pascal Costanza
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <4vs7inF1dc16uU1@mid.individual.net>
Ken Tilton wrote:
> 
> 
> Pascal Costanza wrote:
>> Ken Tilton wrote:
>>
>>>
>>> Zach Beane wrote:
>>>
>>>> "Pillsy" <·········@gmail.com> writes:
>>>>
>>>>
>>>>> Well, two questions about exporting symbols, really. Say I want to set
>>>>> up bindings to captured variables (like IT in anaphoric macros) in
>>>>> packages that I'll be using. Do I want to just export IT and friends,
>>>>> or should I walk through the code and replace them with gensyms or
>>>>> something?
>>>>
>>>>
>>>> This is a bit of a tangent, but: don't write anaphoric macros. Making
>>>> names magically spring into existence without visible bindings is not
>>>> very Lispy.
>>>
>>>
>>> Damn! Now I have to stop using special variables and symbol-macros?!!
>>
>>
>> Special variables and symbol macros don't have that problem.
> 
> Classic rongarretesque unexplained rejoinder trying to bait someone into 
> godknowswhat.

Nope.

Dynamic scoping has its issues, but "magically springing into existence 
without visible bindings" is not one of them.

You have to use a defvar, defparameter or a declaration to bring special 
variables into existence. Likewise, you have to use define-symbol-macro 
and symbol-macrolet to bring symbol macros into existence.

This is actually the same like all the other constructs defining new 
bindings (defun, defmacro, macrolet, flet, let, let*, etc.)

An anaphoric macro can "magically" introduce any of these.

If you have an anaphoric macro from a third-party library and you want 
to nest it, you're screwed. If you design a macro, the fact that you 
could screw other people's code in this way should be a consideration in 
the design of your interface.


Apart from that, happy new year. ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pillsy
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1167688159.014982.252590@h40g2000cwb.googlegroups.com>
Pascal Costanza wrote:
[...]
> An anaphoric macro can "magically" introduce any of these.

Well, yes, that's precisely the point.

> If you have an anaphoric macro from a third-party library and you want
> to nest it, you're screwed.

"Doctor, it hurts when I do this."
"Well, don't do that then!"

I'd think a crucial part of the documentation for any anaphoric macro
would absolutely have to be the bindings it sets up. Nesting them in
their own macros or other macros is something you want to do with care,
but if you're exporting them as part of a library I'd think you should
be set as long as you tell your user what they do.

Otherwise you have a badly documented library.

> If you design a macro, the fact that you
> could screw other people's code in this way should be a consideration in
> the design of your interface.

Right. And I was looking for ways to avoid screwing their code and came
up with two. One being to not actually bind the names but let the
macros walk the code to find them (so no symbols need to be exported)
and the other being to give them funny-looking names (like $IT and
$STEP and $<number>) so that they stick out like a *SPECIAL-VARIABLE*
does.

That means you still can't do some stuff, like nesting, but that just
means these macros are bad solutions to some problems.

> Apart from that, happy new year. ;)

You too. 

Cheers,
Pillsy
From: Pascal Costanza
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <4vg5j6F1bt051U1@mid.individual.net>
Pillsy wrote:
> Well, two questions about exporting symbols, really. Say I want to set
> up bindings to captured variables (like IT in anaphoric macros) in
> packages that I'll be using. Do I want to just export IT and friends,
> or should I walk through the code and replace them with gensyms or
> something?
> 
> Also, I've found I've gotten in the habit of naming captured variables
> like IT names that begin with dollar signs, i.e., $IT, so they stand
> out a bit. Bad, good or indifferent idea?

What you have to keep in mind is that anaphoric macros are only useful 
as surface syntax. Other macros should not expand into anaphoric macros 
because otherwise they may cause unintended capture of the special 
variable names.

Consider AIF being a macro that creates a new implicit binding for IT. 
Now check the following example:

(aif (some-expression ...)
   (some-macro ...
      (+ it 5)))

If SOME-MACRO expands into a use of AIF (or some other anaphoric macro 
introducing a new binding for IT), then the inner (+ it 5) probably 
doesn't do what you expect it to.

So your design should be based on the intended use of your macros. If 
your macros are supposed to be used as regular language constructs that 
other macros can expand into, you should probably better avoid anaphoric 
macros.

Next, clients of anaphoric macros must be able to see the variable name. 
This means that you have to export it from your package and they have to 
import it. Now, IT is a pretty common name for such a purpose, so there 
is a certain level of likeliness that there will be name clashes. This 
means that client code probably ends up in having to say SOME-PACKAGE:IT 
instead of just IT.

One solution, if you insist on using anaphoric macros, is to not 
consider IT not as a regular variable but just as special syntax. In 
other words, you would have to parse the macro body and replace all 
occurences of IT with an internally created variable (via gensym). For 
example, the LOOP macro does it this way. Futhermore, in LOOP, IT is 
recognized by its symbol-name (thus you don't have to import/export 
anything to use it). Maybe that's going a bit too far and a keyword :IT 
would have been sufficient here.

Anyway, you may simply come to the conclusion that this is not worth the 
fuzz and just let the client code decide what name to use...


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Wolfram Fenske
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1168900097.380829.115920@l53g2000cwa.googlegroups.com>
"Pillsy" <·········@gmail.com> writes:

> Well, two questions about exporting symbols, really. Say I want to set
> up bindings to captured variables (like IT in anaphoric macros) in
> packages that I'll be using. Do I want to just export IT and friends,
> or should I walk through the code and replace them with gensyms or
> something?

What about using INTERN, like this:

--8<---------------cut here---------------start------------->8---
(defmacro foo (list-form &body body)
  (let ((it (intern (symbol-name 'it))))
    `(dolist (,it ,list-form)
       ,@body)))
--8<---------------cut here---------------end--------------->8---

This way you wouldn't have to export IT.

--
Wolfram Fenske

A: Yes.
>Q: Are you sure?
>>A: Because it reverses the logical flow of conversation.
>>>Q: Why is top posting frowned upon?
From: Juho Snellman
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <slrneqo0mq.elh.jsnell@sbz-30.cs.Helsinki.FI>
Wolfram Fenske <·····@gmx.net> wrote:
> "Pillsy" <·········@gmail.com> writes:
>
>> Well, two questions about exporting symbols, really. Say I want to set
>> up bindings to captured variables (like IT in anaphoric macros) in
>> packages that I'll be using. Do I want to just export IT and friends,
>> or should I walk through the code and replace them with gensyms or
>> something?
>
> What about using INTERN, like this:
>
> --8<---------------cut here---------------start------------->8---
> (defmacro foo (list-form &body body)
>   (let ((it (intern (symbol-name 'it))))
>     `(dolist (,it ,list-form)
>        ,@body)))
> --8<---------------cut here---------------end--------------->8---
>
> This way you wouldn't have to export IT.

Unfortunately there's no guarantee that *PACKAGE* will be the same
when a use of FOO is read and when it's macroexpanded.

-- 
Juho Snellman
From: Wolfram Fenske
Subject: Re: More questions about exported symbols and general style.
Date: 
Message-ID: <1168901541.002564.125620@51g2000cwl.googlegroups.com>
Juho Snellman <······@iki.fi> writes:

> Wolfram Fenske <·····@gmx.net> wrote:
>> "Pillsy" <·········@gmail.com> writes:

[...]

>> What about using INTERN, like this:
>>
>> --8<---------------cut here---------------start------------->8---
>> (defmacro foo (list-form &body body)
>>   (let ((it (intern (symbol-name 'it))))
>>     `(dolist (,it ,list-form)
>>        ,@body)))
>> --8<---------------cut here---------------end--------------->8---
>>
>> This way you wouldn't have to export IT.
>
> Unfortunately there's no guarantee that *PACKAGE* will be the same
> when a use of FOO is read and when it's macroexpanded.

I see. :-/

--
Wolfram Fenske

A: Yes.
>Q: Are you sure?
>>A: Because it reverses the logical flow of conversation.
>>>Q: Why is top posting frowned upon?