From: Doug Hoyte
Subject: Let Over Lambda chapter 4
Date: 
Message-ID: <34e7da66-0b73-4f36-9cf7-196e2f52df5c@26g2000hsk.googlegroups.com>
Hello comp.lang.lisp,

I have opened up chapter 4 of my book, Let Over Lambda.
This chapter is about read macros.

The following are the "release notes" for the chapter
and some other miscellaneous thoughts.

Best wishes,

Doug

--------LET OVER LAMBDA PRESS RELEASE 2---------

Announcing the release of chapter 4, "Read Macros":

http://letoverlambda.com/index.cl/guest/chap4.html

1) Post-publication additions to chapter 4
2) Smiley Balancing
2) A "Considered Harmful"
3) Why I don't put asterisks on special variables


Post-publication additions to chapter 4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Since Let Over Lambda was published, chapter 4 has changed
more than any other chapter. There are several known errata
that you might like to consider while reading it:

http://letoverlambda.com/index.cl/errata

As described in chapter 4, we can use read macros to make
Edi Weitz's excellent CL-PPCRE library even more convenient:

* (#~m/\w+/ "abcd")

0
4
#()
#()

This works because #~ reads in as a lambda form:

* '#~m/\w+/

(LAMBDA (#:STR2) (CL-PPCRE:SCAN "\\w+" #:STR2))

Let Over Lambda's production code now accepts perl-style
regular expression modifiers. For instance, here is a
case-insensitive regular expression matcher:

* '#~m/abc/i

(LAMBDA (#:STR2) (CL-PPCRE:SCAN "(?i)abc" #:STR2))

Notice how an embedded modifier is used. This is so that
the #~ read macro will create constant string regular
expressions. When using #~, regular expressions are
guaranteed to be pre-compiled with CL-PPCRE's compiler
macro.

The final additions to chapter 4's regular expression
API are the macros if-match and when-match. These
macros automate the common task of using #'subseq
to extract and bind CL-PPCRE matches. Just like perl,
these macros use the symbols $1, $2, etc:

* (if-match (#~m/hello (\w+)/ "hello world")
    (format t "First match: ~a~%" $1)
    (format t "Didn't match"))

First match: world
NIL

Unlike perl where $1, $2, etc are global variables, we bind
these matches in the lexical scope of the if-match/when-match
forms. To be perfectly honest, they are bound in the
sub-lexical scope of these forms. For instance, the
following form will throw an error because $2 is "unbound"
in the nested if-match.

* (if-match (#~m/(\w+) (\w+)/ "hello world")
    (if-match (#~m/he(ll)o/ $1)
      $2))

Error in function "Top-Level Form":  ifmatch: too few matches

But you don't need to think about this to use the API. If
this doesn't make sense, don't worry. It will all become
clear once you read Section 6.6, "Sub-Lexical Scope".

Finally, to use this functionality, make sure you load
CL-PPCRE *before* you load lol.lisp:

http://letoverlambda.com/lol.lisp

HCSW: Porting perl to lisp, one step at a time.


Smiley Balancing
~~~~~~~~~~~~~~~~

I remember Kent Pitman wrote once that an unbalanced
parenthesis can throw off his whole day. Me too. In fact,
keeping parens balanced is so important to me that I
have adopted a somewhat peculiar pattern to combat
unbalanced parens.

This is what I call the "happy balancer":

(defun match-open-paren (str)
  (#~m/[(]/ str)) ;)

And the "sad balancer":

(defun match-close-paren (str) ;(
  (#~m/[)]/ str))


A "Considered Harmful"
~~~~~~~~~~~~~~~~~~~~~~

I don't consider any programming techniques harmful.
This is just an amusing observation I have made since
publishing Let Over Lambda.

The function that handles the #~ reading is named
|#~-reader|. This is a fun use of the fact that lisp
symbols can contain any characters you please. I got
this idea from CLtL2. However, I have since changed my
mind about this naming convention for dispatched read
macros. The problem is a latent collision with these
names and the #| and |# read macros. Consider what
will happen if you comment out code that contains
such a symbol:

#|
... |#~-reader| ...
|#

In hindsight, a better naming convention, at least for
Let Over Lambda, would perhaps have been |reader-for-#~|.


Why I don't put asterisks on special variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Several people have asked me to clarify why I don't use the
*earmuff* convention for special variables, so here goes.

First of all, I'm not convinced that unexpected collisions
are unconditionally bad. The way I look at it, you always
learn something when you encounter a collision and you
never learn anything when you don't.

My instinct tells me that the earmuff convention is
dangerous, or at least that it isn't nearly as open-shut
an issue as everyone seems to think. For example, what
sort of binding is this?

(let (*hello*)
  ...)

It is a lexical binding because I haven't declared *hello*
to be special yet. But that's not what you thought when
you first looked at it, was it?

Or consider this: If you are dogmatic about the earmuffs,
why stop there? How about a print-name convention for
distinguishing between macros and functions? Instead of
with-open-file, we could call it ^with-open-file^ so that
we wouldn't need to remember that it is a macro instead of
a function. This convention would also reduce collisions
like accidentally trying to funcall a macro.

Would you use this convention? No, of course you wouldn't.
It's stupid. Instead of relying on a semantically meaningless
print-name convention, it is a better idea to just name
your macros and functions appropriately in the first place.

I guess I'm trying to say that I consider the following fact
to be a feature, not a flaw of Common Lisp: Functions and
macros, along with lexical and special bindings, look the
same in Common Lisp.

Hope this helps clarify my reasoning,

Doug Hoyte
Strategic Lead API Designer, HCSW

PS. Come to think of it, not even the standard is dogmatic
about the earmuffs. There are at least 6 special variables
defined by ANSI that don't begin and end with asterisks.

From: Kaz Kylheku
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <145bbbf3-43fa-4fb9-a0a4-f18e878d4d43@z16g2000prn.googlegroups.com>
On Jun 27, 4:37 pm, Doug Hoyte <····@hcsw.org> wrote:
> Or consider this: If you are dogmatic about the earmuffs,
> why stop there? How about a print-name convention for
> distinguishing between macros and functions? Instead of
> with-open-file, we could call it ^with-open-file^ so that
> we wouldn't need to remember that it is a macro instead of
> a function.

Doh, the macro name already has a convention: it starts with WITH-.

Using an ``earmuffs'' symbol name for a variable which isn't special
is just as deceptive as using function-like names for macros, or macro-
like names for functions. For instance, you wouldn't call a function
DEFINE-FOO, FOO-BIND, WITH-FOO, etc.

> This convention would also reduce collisions
> like accidentally trying to funcall a macro.
>
> Would you use this convention? No, of course you wouldn't.
> It's stupid. Instead of relying on a semantically meaningless
> print-name convention, it is a better idea to just name
> your macros and functions appropriately in the first place.

How to name things is a print-name convention. The P and -P suffixes
for predicates are a print convention, DEF or DEFINE- are a
convention, dashes to separate words rather than underscores or
CamelCase are a convention, etc.

> I guess I'm trying to say that I consider the following fact
> to be a feature, not a flaw of Common Lisp: Functions and
> macros, along with lexical and special bindings, look the
> same in Common Lisp.

The problem is that when you create a special variable, the symbol is
endowed with a pervasive property which makes all bindings of that
symbol special! By pervasive we mean that this property transcends
scope.

So if you don't use the earmuffs convention, you can create a real
problem for yourself. You might DEFVAR some variable FOO, making it
pervasively special, and then in some nested scope, you might use FOO
expecting it to be a lexical variable which is captured by closures.
Surprise, surprise!

That problem has no analog in Common Lisp, between macros and
functions.
If I use FOO as a macro name in one scope, it does not automatically
become a macro in other scopes even if I want it to be a function. It
doesn't acquire a pervasive ``macroness''.

Think a little. If Lispers have some convention, there is usually a
good reason for it. Generally, they aren't a stupid lot. :)
From: Doug Hoyte
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <3ccc160b-e2fb-4d5a-9f17-6b862998dd2b@f63g2000hsf.googlegroups.com>
On Jun 28, 1:25 am, Kaz Kylheku <········@gmail.com> wrote:

> You might DEFVAR some variable FOO, making it
> pervasively special, and then in some nested scope, you might use FOO
> expecting it to be a lexical variable which is captured by closures.

If you want to use the same symbol for lexical and special
bindings you are free to declare the symbol locally special.

> Think a little. If Lispers have some convention, there is usually a
> good reason for it. Generally, they aren't a stupid lot. :)

I never meant to say that and I'm very sorry if that's how it
came out.

Doug
From: Pascal J. Bourguignon
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <87ej6hgase.fsf@hubble.informatimago.com>
Doug Hoyte <····@hcsw.org> writes:

> On Jun 28, 1:25�am, Kaz Kylheku <········@gmail.com> wrote:
>
>> You might DEFVAR some variable FOO, making it
>> pervasively special, and then in some nested scope, you might use FOO
>> expecting it to be a lexical variable which is captured by closures.
>
> If you want to use the same symbol for lexical and special
> bindings you are free to declare the symbol locally special.

Yes.  but the point is that there is no declaration in Common Lisp to
make a symbol locally lexical.  Once special, forever special.


-- 
__Pascal_Bourguignon__               _  Software patents are endangering
()  ASCII ribbon against html email (o_ the computer industry all around
/\  1962:DO20I=1.100                //\ the world http://lpf.ai.mit.edu/
    2001:my($f)=`fortune`;          V_/   http://petition.eurolinux.org/
From: Duane Rettig
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <o0lk0pd16m.fsf@gemini.franz.com>
···@informatimago.com (Pascal J. Bourguignon) writes:

> Doug Hoyte <····@hcsw.org> writes:
>
>> On Jun 28, 1:25�am, Kaz Kylheku <········@gmail.com> wrote:
>>
>>> You might DEFVAR some variable FOO, making it
>>> pervasively special, and then in some nested scope, you might use FOO
>>> expecting it to be a lexical variable which is captured by closures.
>>
>> If you want to use the same symbol for lexical and special
>> bindings you are free to declare the symbol locally special.
>
> Yes.  but the point is that there is no declaration in Common Lisp to
> make a symbol locally lexical.  Once special, forever special.

Correct - none exists in Common Lisp.  However, Common Lisp doesn't
preclude such a declaration being possible as an extension, especially
if a CL implementation is itself extended to provide the
define-declaration function, roughly as it appears in CLtL2.  In my
ILC2005 tutorial on Environments Access, I gave one example of
defining a lexical declaration - note that I don't necessarily think
that such a declaration would be a Good Thing, so I didn't actually
include it as an example in the free download of the module:
http://www.lispwire.com/entry-proganal-envaccess-des 

but here is a proof-of-concept demonstration in Allegro CL 8.1:

CL-USER(1): (defvar pie pi)
PIE
CL-USER(2): (compile (defun circ (rad)
                       (* pie rad rad)))
CIRC
NIL
NIL
CL-USER(3): (circ 10)
314.1592653589793d0
CL-USER(4): (compile (defun foo (x)
                       (let ((pie 22/7))
                         (circ x))))
FOO
NIL
NIL
CL-USER(5): (foo 10)
2200/7
CL-USER(6): (float *)
314.2857
CL-USER(7): (sys:define-declaration sys::lexical (&rest vars)
              nil
             :variable
             (lambda (declaration env)
               (declare (ignore env))
               (let* ((spec '(lexical t))
                      (res (mapcar #'(lambda (x) (cons x spec))
                                   (cdr declaration))))
                 (values :variable res))))
SYSTEM::LEXICAL
CL-USER(8): (compile (defun foo (x)
                       (let ((pie 22/7))
                         (declare (sys::lexical pie))
                         (circ x))))
; While compiling FOO:
Warning: Variable PIE is never used.
FOO
T
NIL
CL-USER(9): (foo 10)
314.1592653589793d0
CL-USER(10): 

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Kaz Kylheku
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <c722dd33-6c08-4f3e-9013-259dab86ae9a@z24g2000prf.googlegroups.com>
On Jun 27, 10:45 pm, Doug Hoyte <····@hcsw.org> wrote:
> On Jun 28, 1:25 am, Kaz Kylheku <········@gmail.com> wrote:
>
> > You might DEFVAR some variable FOO, making it
> > pervasively special, and then in some nested scope, you might use FOO
> > expecting it to be a lexical variable which is captured by closures.
>
> If you want to use the same symbol for lexical and special
> bindings you are free to declare the symbol locally special.

That is true, but if such a declaration was required (i.e. if there
was no support for a pervasive dynamic binding property attached to a
symbol), then effectively dynamic variables would be second-class
citizens in Lisp.

It helps to look at history also. Before Lisp had lexical scope, there
were only dynamic variables. (Emacs Lisp is a major example of a
surviving dialect which is like this).

The ``*earmuffs*'' notation is used in these pre-lexical-scope
dialects to distinguish variables which are intended to be global (and
overrideable) from variables that behave like locals. Without the
notation, you can create bugs: unintentionally overriding some
important global variable when you only wanted to simulate a local
variable.

Common Lisp's implementation of dynamic scope is such that it allows
you to program in the style of these dynamically scoped dialects, with
pretty much exactly the same convenience.

Suppose that you had to use (DECLARE (SPECIAL ...)) whenever you
wanted to temporarily override variables like *STANDARD-OUTPUT* and
*PRINT-BASE*. It would be not only a pain in the neck, but error
prone. Forget the declaration, and the effect you wanted will not
occur. The number will be printed in the wrong base, the output will
go to the wrong stream.

So as it stands, you can choose your style for using dynamic
variables. You can avoid using DEFVAR and DEFPARAMETER, and only use
local declarations to make variables special. In this style, you can
avoid the *...* convention, if you are so inclined.

But if you program in the predominant dynamic scoping style, based on
defining pervasively special variables at the top level, then it makes
sense to follow that convention.

In practice, even when Lisp programmers implement some dynamically
scoping hack in the internals of something, whereby a function
responds to some secret special variable set up by another function,
we still use the *...* notation for that variable, for no other reason
than that it alerts the reader that data is being communicated using a
dynamic variable.

You have to consider one thing: the reason you set up the binding for
a special variable is for the sake of some code which will examine the
variable. And in that code, the variable is a free reference! I.e.
here is always some leaf level in the call tree where the specials are
nothing more than free references, with no declaration in scope. The
*...* notation effectively allows these free references to visually
stand out.
From: Paul Donnelly
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <87d4m09opb.fsf@plap.localdomain>
Kaz Kylheku <········@gmail.com> writes:

> On Jun 27, 10:45 pm, Doug Hoyte <····@hcsw.org> wrote:
>> On Jun 28, 1:25 am, Kaz Kylheku <········@gmail.com> wrote:
>>
>> > You might DEFVAR some variable FOO, making it
>> > pervasively special, and then in some nested scope, you might use FOO
>> > expecting it to be a lexical variable which is captured by closures.
>>
>> If you want to use the same symbol for lexical and special
>> bindings you are free to declare the symbol locally special.
>
> That is true, but if such a declaration was required (i.e. if there
> was no support for a pervasive dynamic binding property attached to a
> symbol), then effectively dynamic variables would be second-class
> citizens in Lisp.
>
> It helps to look at history also. Before Lisp had lexical scope, there
> were only dynamic variables. (Emacs Lisp is a major example of a
> surviving dialect which is like this).
>
> The ``*earmuffs*'' notation is used in these pre-lexical-scope
> dialects to distinguish variables which are intended to be global (and
> overrideable) from variables that behave like locals.

Although ironically Emacs doesn't actually use ``*earmuffs*'' (sometimes
I wish it did).
From: Rainer Joswig
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <joswig-0A314F.02315328062008@news-europe.giganews.com>
In article 
<····································@26g2000hsk.googlegroups.com>,
 Doug Hoyte <····@hcsw.org> wrote:

...

> Why I don't put asterisks on special variables
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Several people have asked me to clarify why I don't use the
> *earmuff* convention for special variables, so here goes.
> 
> First of all, I'm not convinced that unexpected collisions
> are unconditionally bad. The way I look at it, you always
> learn something when you encounter a collision and you
> never learn anything when you don't.
> 
> My instinct tells me that the earmuff convention is
> dangerous, or at least that it isn't nearly as open-shut
> an issue as everyone seems to think. For example, what
> sort of binding is this?
> 
> (let (*hello*)
>   ...)
> 
> It is a lexical binding because I haven't declared *hello*
> to be special yet. But that's not what you thought when
> you first looked at it, was it?

Naming conventions are not enforced. But they
mark intentions. *hello* tells us that it
was supposed to be a special variable and if it
isn't, it better be fixed in the source.

Naming special variables like that should give
the reader (remember the quote that code is
not just for computers to execute, but also for human
readers) some additional hints.
 
> Or consider this: If you are dogmatic about the earmuffs,
> why stop there?

Right, the are lots of naming conventions you find in Lisp
software. %foo for internal definitions or non-portable
definitions. fooF for macros that take a place
like INCF. predicate-p for predicates that return a
boolean value. +foo+ for constants. make-something
for functions that create some kind of object.
using-foo for something that uses some object
in its scope. Plus many more.

> How about a print-name convention for
> distinguishing between macros and functions? Instead of
> with-open-file, we could call it ^with-open-file^ so that
> we wouldn't need to remember that it is a macro instead of
> a function. This convention would also reduce collisions
> like accidentally trying to funcall a macro.

the prefix with- is already the convention that
tells us that it is a macro creating some kind of
scope. There are other conventions used for special
types of macros like

* DEFsomething or DEFINE-SOMETHING
* doING
* DOsomething

> Would you use this convention? No, of course you wouldn't.

I already use the with- convention.

> It's stupid. Instead of relying on a semantically meaningless
> print-name convention, it is a better idea to just name
> your macros and functions appropriately in the first place.
> 
> I guess I'm trying to say that I consider the following fact
> to be a feature, not a flaw of Common Lisp: Functions and
> macros, along with lexical and special bindings, look the
> same in Common Lisp.

They don't look the same in code I read. Pick any
Lisp application, look at the main files and
count the different naming conventions used. 
There are lots of naming conventions.
For macros there are also lots of structure conventions.
IMHO naming conventions are extremely important and
can be very helpful. My goal is not to make everything
to look the same (foo bar baz). My goal would be to
use appropriate naming for the program structure at
hand. Personally I like special variables to stand out.
There are some other conventions I'm not so interested
in - like everywhere encoding type information
in identifiers. 

> Hope this helps clarify my reasoning,
> 
> Doug Hoyte
> Strategic Lead API Designer, HCSW
> 
> PS. Come to think of it, not even the standard is dogmatic
> about the earmuffs. There are at least 6 special variables
> defined by ANSI that don't begin and end with asterisks.

Most special variables in ANSI CL that are intended to be bound are
following the *foo* convention.

-- 
http://lispm.dyndns.org/
From: Doug Hoyte
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <71ef8db9-7e48-449e-8f48-f5d2e4c9286d@b1g2000hsg.googlegroups.com>
On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:

Hi Rainer,

Thanks for your comments.

> * DEFsomething or DEFINE-SOMETHING
> * doING
> * DOsomething

> > Would you use this convention? No, of course you wouldn't.

> I already use the with- convention.

Sorry I think there was some confusion. I myself like and use
all the conventions you mentioned above. I was only suggesting
that conventions shouldn't supersede proper naming of functions,
macros, or variables. Because with-open-file is named well, it
is easy to remember it is a macro.

I also understand why people like the earmuffs and have nothing
against their use. I was just trying to explain why I don't
use them.

Best,

Doug
From: Terry Sullivan
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <aaa2$4865aaf9$186091bf$5523@KNOLOGY.NET>
Doug Hoyte wrote:
> On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:
> 
> Hi Rainer,
> 
> Thanks for your comments.
> 
>> * DEFsomething or DEFINE-SOMETHING
>> * doING
>> * DOsomething
> 
>>> Would you use this convention? No, of course you wouldn't.
> 
>> I already use the with- convention.
> 
> Sorry I think there was some confusion. I myself like and use
> all the conventions you mentioned above. I was only suggesting
> that conventions shouldn't supersede proper naming of functions,
> macros, or variables. Because with-open-file is named well, it
> is easy to remember it is a macro.

Ok, I'm not quite clear on this part. Why is it important to know that 
with-open-file is a macro? Aren't we just supposed to use it just like a 
function?

Actually, until I saw this message, I had no idea that it is a macro.

Ts
From: Vassil Nikolov
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <snzr6ainqnh.fsf@luna.vassil.nikolov.name>
On Fri, 27 Jun 2008 22:07:36 -0500, Terry Sullivan <··············@drifter.net> said:

| ...
| Why is it important to know that with-open-file is a macro? Aren't
| we just supposed to use it just like a function?

  No, of course not.  The subform following WITH-OPEN-FILE is not
  evaluated according to the rules of function application, for
  example.

  By the way, to me `WITH-' forms introduce (dynamic) extent, rather
  than (lexical) scope.  For introducing scope, to me the naming
  convention is to use `-BIND-' or `-LET-'.  (Using `WITH' as a
  preposition in LOOP forms is a little different case.)

  Also, the convention of surrounding names of special variables with
  asterisks is indispensable.  They simply _must_ stand out---and
  never, ever clash with lexical variables (the programmer must not
  worry that writing (LET ((FOO ...)) ...) would inadvertently
  introduce a dynamic binding).  And since special variables should be
  used sparingly, these asterisks would not get annoying anyway.

  ---Vassil.


-- 
Peius melius est.  ---Ricardus Gabriel.
From: Doug Hoyte
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <a5268677-66ed-4ee9-ba38-a4e6a06b22e9@l64g2000hse.googlegroups.com>
On Jun 28, 12:13 am, Vassil Nikolov <···············@pobox.com> wrote:

>   By the way, to me `WITH-' forms introduce (dynamic) extent, rather
>   than (lexical) scope.

I don't usually associate the with- macros as creating either
lexical or special bindings because usually they can create
both. For instance, compare:

(with-output-to-string (o) ; assume o is not special
  ...)

vs

(with-output-to-string (*standard-output*)
  ...)

Because lexical bindings share syntax with special bindings,
for such macros you get an extra meaning "for free".

When I said this:

> I guess I'm trying to say that I consider the following fact
> to be a feature, not a flaw of Common Lisp: Functions and
> macros, along with lexical and special bindings, look the
> same in Common Lisp.

I meant that I consider both of these facts features:

* Invoking a function looks the same as invoking a macro.
* Binding a special variable looks the same as binding
  a lexical variable (with or without earmuffs).

Doug
From: Vassil Nikolov
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <snzk5g9obza.fsf@luna.vassil.nikolov.name>
On Fri, 27 Jun 2008 22:19:13 -0700 (PDT), Doug Hoyte <····@hcsw.org> said:

| On Jun 28, 12:13�am, Vassil Nikolov <···············@pobox.com> wrote:
|| � By the way, to me `WITH-' forms introduce (dynamic) extent, rather
|| � than (lexical) scope.

| I don't usually associate the with- macros as creating either
| lexical or special bindings because usually they can create
| both. For instance, compare:

| (with-output-to-string (o) ; assume o is not special
|   ...)

| vs

| (with-output-to-string (*standard-output*)
|   ...)

| Because lexical bindings share syntax with special bindings,
| for such macros you get an extra meaning "for free".

  Any creation of variable bindings by `WITH-' forms introducing
  (dynamic) extent is secondary and when they do it, it is subordinate
  to their primary function, which is to provide some facility (such
  as an open stream) or to exercise some effect for a given period of
  time.  For one, `WITH-' forms may not create any variable bindings
  at all (e.g. WITH-SIMPLE-RESTART, WITH-STANDARD-IO-SYNTAX).  Then,
  even when they do, there are restrictions on the useful things one
  can do with the bindings arising from the extent of the facility
  provided by the `WITH-' form, even when the binding itself does not
  impose such restrictions.  For example, compare

    (with-open-file (s "/dev/null") (funcall #'(lambda () (read s nil 'eof))))
    => eof

  to

    (funcall (with-open-file (s "/dev/null") #'(lambda () (read s nil 'eof))))
    ;; ERROR

  where the latter fails not because of trouble with the binding of S
  in the closure, but because of trouble with the value to which S is
  bound (so even with proper lexical scoping, such closures are only
  good as downward funargs).  In other words, such a `WITH-' form is
  about programming with state.


  Note: the convention that `WITH-' forms should be about extent,
  rather than scope, is certainly more subjective and weaker than a
  few other conventions mentioned in this thread.  For example, I'd
  rather that, say, WITH-ACCESSORS [*] was named differently, but I
  wouldn't argue for a different name for such a form the way I would
  argue for not omitting asterisks from the name of a special
  variable.  Of course, it might be better to take this as simply a
  case of homonymy, where `WITH-' just means different things in
  different contexts, instead of always trying to arrive at
  unambiguous naming conventions.

  [*] Perhaps ALET, by analogy to FLET; how does LET-ACCESSORS sound
      to a native speaker (from "_let_ ... be _accessors_ for ...")?

  ---Vassil.


-- 
Peius melius est.  ---Ricardus Gabriel.
From: Terry Sullivan
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <e278e$48685b86$186091bf$1486@KNOLOGY.NET>
Vassil Nikolov wrote:
> On Fri, 27 Jun 2008 22:07:36 -0500, Terry Sullivan <··············@drifter.net> said:
> 
> | ...
> | Why is it important to know that with-open-file is a macro? Aren't
> | we just supposed to use it just like a function?
> 
>   No, of course not.  The subform following WITH-OPEN-FILE is not
>   evaluated according to the rules of function application, for
>   example.
> 
>   By the way, to me `WITH-' forms introduce (dynamic) extent, rather
>   than (lexical) scope.  For introducing scope, to me the naming
>   convention is to use `-BIND-' or `-LET-'.  (Using `WITH' as a
>   preposition in LOOP forms is a little different case.)

I guess my definition of "just like a function" is a little different 
than yours.

To me, the USE of a macro, not the definition of it, is just more code 
that just happens to expand into more code at compile time. Yes, it can 
introduce new and different syntax like LOOP does, but that's just par 
for the course.

I can see, now that I think of it, how WITH- probably implies that an 
macro expansion is likely. I'm still not totally convinced that it would 
be necessary to know that before using it.

Ts
From: Vassil Nikolov
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <snzy74nmqrj.fsf@luna.vassil.nikolov.name>
On Sun, 29 Jun 2008 23:18:37 -0500, Terry Sullivan <··············@drifter.net> said:

| Vassil Nikolov wrote:
|| On Fri, 27 Jun 2008 22:07:36 -0500, Terry Sullivan <··············@drifter.net> said:
|| | ...
|| | Why is it important to know that with-open-file is a macro? Aren't
|| | we just supposed to use it just like a function?
|| No, of course not.  The subform following WITH-OPEN-FILE is not
|| evaluated according to the rules of function application, for
|| example.
|| ...

| I guess my definition of "just like a function" is a little different
| than yours.

| To me, the USE of a macro, not the definition of it, is just more code
| that just happens to expand into more code at compile time. Yes, it
| can introduce new and different syntax like LOOP does, but that's just
| par for the course.

| I can see, now that I think of it, how WITH- probably implies that an
| macro expansion is likely. I'm still not totally convinced that it
| would be necessary to know that before using it.

  What is necessary to know is whether the form at hand has
  idiosyncratic evaluation rules or not.  If it is a function call, it
  certainly doesn't; if it is a macro call (or a special form), then
  it well may.  (And then new syntax implies idiosyncratic evaluation
  rules, of course.)

  And by the way, another reason to care if something is a function or
  not is to know whether it can be used in higher-order programming.
  (Not possible even with macros (or special operators) whose
  arguments get evaluated like those in a function call.)

  ---Vassil.


-- 
Peius melius est.  ---Ricardus Gabriel.
From: Vsevolod
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <023054c3-9d06-4a90-ae8b-eab7b25e1fa2@m73g2000hsh.googlegroups.com>
Hi Doug,
I've read the 4 chapters of your book, which are on-line. It was quite
interesting, so thanks a lot. The most interesting to me was a good
point of view on fundamentals.

I would suggest, that you integrate the cl-ppcre read macros into the
cl-ppcre package. But definitely it should be optional (like, for
example, sql-read-syntax in clsql).

Speaking about DEFMACRO!, I think you try to solve the non-problem, as
I don't see how for those, who fully understand, when to use GENSYM
and ONCE-ONLY, it's difficult to use this idioms. The problem is for
the beginners, who don't yet 'feel' it. And for them with the usage of
DEFMACRO! the hardest, i.e. the decision part remains.

Would be glad to see other parts of your book on-line
Vsevolod
From: Doug Hoyte
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <66b36ee2-e3a9-47c2-87f7-8fb95d3176e3@x35g2000hsb.googlegroups.com>
Hi Vsevolod,

Thanks for your comments.

On Jul 2, 3:25 pm, Vsevolod <········@gmail.com> wrote:
> Speaking about DEFMACRO!, I think you try to solve the non-problem, as
> I don't see how for those, who fully understand, when to use GENSYM
> and ONCE-ONLY, it's difficult to use this idioms. The problem is for
> the beginners, who don't yet 'feel' it. And for them with the usage of
> DEFMACRO! the hardest, i.e. the decision part remains.

The idea behind defmacro! is to make proven macro programming
techniques
more available, not to replace them. I personally am skeptical about
macro languages that claim to do this.

Best,

Doug
From: Rainer Joswig
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <joswig-F23196.11101628062008@news-europe.giganews.com>
In article <···························@KNOLOGY.NET>,
 Terry Sullivan <··············@drifter.net> wrote:

> Doug Hoyte wrote:
> > On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:
> > 
> > Hi Rainer,
> > 
> > Thanks for your comments.
> > 
> >> * DEFsomething or DEFINE-SOMETHING
> >> * doING
> >> * DOsomething
> > 
> >>> Would you use this convention? No, of course you wouldn't.
> > 
> >> I already use the with- convention.
> > 
> > Sorry I think there was some confusion. I myself like and use
> > all the conventions you mentioned above. I was only suggesting
> > that conventions shouldn't supersede proper naming of functions,
> > macros, or variables. Because with-open-file is named well, it
> > is easy to remember it is a macro.
> 
> Ok, I'm not quite clear on this part. Why is it important to know that 
> with-open-file is a macro? Aren't we just supposed to use it just like a 
> function?

No.

For a function call we have a simple evaluation rule:
  * check if we have a function call
  * evaluate the arguments left to right
  * call the function with the evaluated arguments

The syntax is also simple:

(some-function arg1 ... argn)

Macros are completely different. They allow you to
use all kinds of fancy syntax (check the LOOP macro)
and the forms inside the macro call maybe evaluation
never, once or even many times.

A simple use of WITH-OPEN-FILE:

(with-open-file (stream pathname) (read stream))

You simply can't do this:

(defparameter *my-form* '(stream pathname))

(with-open-file *my-form* (read stream))

It does not work. WITH-OPEN-FILE has a syntax and it looks like this:

 with-open-file (stream filespec options*) declaration* form*

You have to know the syntax of a macro, if you want to use it.
The means only if you have a macro (or one of the built-in
special forms), you have to understand syntax.

Function calls all have the same syntax.

That (foo-function arg) and (foo-macro arg) look similar
also does not make it behave the same way during evaluation.

You really want to follow some conventions when you design your
macros, so that the naming is consistent with existing practice
and the syntax is also consistent with existing practice.
Both helps the reader to understand the code.


> 
> Actually, until I saw this message, I had no idea that it is a macro.
> 
> Ts

-- 
http://lispm.dyndns.org/
From: Terry Sullivan
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <d2777$48686741$186091bf$30832@KNOLOGY.NET>
Rainer Joswig wrote:
> In article <···························@KNOLOGY.NET>,
>  Terry Sullivan <··············@drifter.net> wrote:
> 
>> Doug Hoyte wrote:
>>> On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:

...snip...

>>> Sorry I think there was some confusion. I myself like and use
>>> all the conventions you mentioned above. I was only suggesting
>>> that conventions shouldn't supersede proper naming of functions,
>>> macros, or variables. Because with-open-file is named well, it
>>> is easy to remember it is a macro.
>> Ok, I'm not quite clear on this part. Why is it important to know that 
>> with-open-file is a macro? Aren't we just supposed to use it just like a 
>> function?
> 
> No.
> 
> For a function call we have a simple evaluation rule:
>   * check if we have a function call
>   * evaluate the arguments left to right
>   * call the function with the evaluated arguments
> 
> The syntax is also simple:
> 
> (some-function arg1 ... argn)
> 
> Macros are completely different. They allow you to
> use all kinds of fancy syntax (check the LOOP macro)
> and the forms inside the macro call maybe evaluation
> never, once or even many times.

I'm aware that macros can introduce their own syntax.

>
> A simple use of WITH-OPEN-FILE:
> 
> (with-open-file (stream pathname) (read stream))
> 
> You simply can't do this:

Ok. I wasn't suggesting that you could.

> 
> (defparameter *my-form* '(stream pathname))
> 
> (with-open-file *my-form* (read stream))
> 
> It does not work. WITH-OPEN-FILE has a syntax and it looks like this:
> 
>  with-open-file (stream filespec options*) declaration* form*
> 
Right...

> You have to know the syntax of a macro, if you want to use it.
> The means only if you have a macro (or one of the built-in
> special forms), you have to understand syntax.
> 
> Function calls all have the same syntax.

Everything has syntax. If I need to use something, I look up what 
arguments or syntax is needed. Been there, done that. The syntax wasn't 
what I was interested in.

> 
> That (foo-function arg) and (foo-macro arg) look similar
> also does not make it behave the same way during evaluation.

This is the part that I'm interested in. The ways that (foo-macro arg) 
and (foo-function arg) behave differently. Beyond the part where the 
macro expand at compile time and the function is evaluated at runtime.

> 
> You really want to follow some conventions when you design your
> macros, so that the naming is consistent with existing practice
> and the syntax is also consistent with existing practice.
> Both helps the reader to understand the code.

Not an issue, I'm not writing any macro's yet, I'm just using 
pre-existing ones. Nor am I making any arguments about naming conventions.

Ts
From: Marco Antoniotti
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <7667554c-81fe-41ef-9818-e7166c4f3007@s50g2000hsb.googlegroups.com>
On Jun 28, 3:34 am, Doug Hoyte <····@hcsw.org> wrote:
> On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:
>
> Hi Rainer,
>
> Thanks for your comments.
>
> > * DEFsomething or DEFINE-SOMETHING
> > * doING
> > * DOsomething
> > > Would you use this convention? No, of course you wouldn't.
> > I already use the with- convention.
>
> Sorry I think there was some confusion. I myself like and use
> all the conventions you mentioned above. I was only suggesting
> that conventions shouldn't supersede proper naming of functions,
> macros, or variables. Because with-open-file is named well, it
> is easy to remember it is a macro.
>
> I also understand why people like the earmuffs and have nothing
> against their use. I was just trying to explain why I don't
> use them.
>

The point is that programs are written to be *read* (syntactic pun
intended :) ).  Unless of course you are a Perl programmer :) If I
read a piece of CL and I see an earmuffed symbol I am alerted - by
convention - to look for the related DEFVAR, DEFPARAMETER or SPECIAL
declaration.  If I don't see it, I may later on waste time retracing
the variable to the declaring form.  Conventions do have their use.
Why not indent code as in

(defun fact (x) (
   if (zerop x)
      1
      (* x (fact (1- x))
   )
)

and not as M-C-q in Emacs would? :)

Cheers
--
Marco
From: Doug Hoyte
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <51e7e387-9154-4b54-8fc2-22e7df261f0e@a70g2000hsh.googlegroups.com>
On Jun 28, 3:36 am, Marco Antoniotti <·······@gmail.com> wrote:
> The point is that programs are written to be *read*

I write programs to run them.

> Unless of course you are a Perl programmer :)

Yes, and very proud of it. :)

> If I
> read a piece of CL and I see an earmuffed symbol I am alerted - by
> convention - to look for the related DEFVAR, DEFPARAMETER or SPECIAL
> declaration.

When reading other people's code I never trust conventions. In
Common Lisp I find #'describe useful for discovering such info.

> Conventions do have their use.

I agree, I just personally don't think this one is necessary.

Best,

Doug
From: Duane Rettig
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <o0prq1d2wi.fsf@gemini.franz.com>
Doug Hoyte <····@hcsw.org> writes:

> On Jun 28, 3:36�am, Marco Antoniotti <·······@gmail.com> wrote:
>> The point is that programs are written to be *read*
>
> I write programs to run them.

Debugging and maintenance is 80% of the programming experience for any
substantial program.  For that to be workable, either the program has
to be readable or you must have a very good memory...

>> Unless of course you are a Perl programmer :)
>
> Yes, and very proud of it. :)
>
>> If I
>> read a piece of CL and I see an earmuffed symbol I am alerted - by
>> convention - to look for the related DEFVAR, DEFPARAMETER or SPECIAL
>> declaration.
>
> When reading other people's code I never trust conventions. In
> Common Lisp I find #'describe useful for discovering such info.

Describe doesn't take an environment argument, and as such does not
provide information on lexical variables or names of things defined in
tempoorary environments, such as the compilation environment.  Thus
describe only is useful in determining global information about an
object, and when the object is a symbol, you may be misplacing your
trust anyway.

>> Conventions do have their use.
>
> I agree, I just personally don't think this one is necessary.

No tool is necessary, but that doesn't remove the usefulness of the
tool.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Rainer Joswig
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <joswig-9B163E.10422928062008@news-europe.giganews.com>
In article 
<····································@a70g2000hsh.googlegroups.com>,
 Doug Hoyte <····@hcsw.org> wrote:

> On Jun 28, 3:36�am, Marco Antoniotti <·······@gmail.com> wrote:
> > The point is that programs are written to be *read*
> 
> I write programs to run them.

SICP foreword:

'To appreciate programming as an intellectual activity in its own
 right you must turn to computer programming; you must read and
 write computer programs -- many of them.'


SICP Preface to the First Edition:

'First, we want to establish the idea that a computer language is
 not just a way of getting a computer to perform operations but
 rather that it is a novel formal medium for expressing ideas
 about methodology. Thus, programs must be written for people
 to read, and only incidentally for machines to execute.


> 
> > Unless of course you are a Perl programmer :)
> 
> Yes, and very proud of it. :)
> 
> > If I
> > read a piece of CL and I see an earmuffed symbol I am alerted - by
> > convention - to look for the related DEFVAR, DEFPARAMETER or SPECIAL
> > declaration.
> 
> When reading other people's code I never trust conventions. In
> Common Lisp I find #'describe useful for discovering such info.

I'm not going to call DESCRIBE on all all variables I see
on the screen to see which are 'special'. Especially
not on those where the source code hasn't been loaded
into Lisp yet.

For me the default are lexical variables. I can see
in the text where those are coming from and I can
see where the next enclosing binding form is. For special variables
this is not possible - the call chain at runtime
with possible rebindings determines the value of the
variable. I want those possible non-local effects to
be visible in the source. I want to see which variable
can be possibly have a different, remote bindings.

> 
> > Conventions do have their use.
> 
> I agree, I just personally don't think this one is necessary.
> 
> Best,
> 
> Doug

-- 
http://lispm.dyndns.org/
From: David Golden
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <DXA9k.26077$j7.470235@news.indigo.ie>
Doug Hoyte wrote:


>> Conventions do have their use.
> 
> I agree, I just personally don't think this one is necessary.
>

I think it's pretty much necessary in _CL_, but I do sometimes wish 
special variables were neatly separated from lexical variables, like
islisp with its defdynamic/dynamic-let/dynamic

Of course there could have been read syntax for (dynamic blah) like
#'blah is read syntax for (function blah) e.g. *blah
From: Pascal J. Bourguignon
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <87zlp4ed96.fsf@hubble.informatimago.com>
David Golden <············@oceanfree.net> writes:

> Doug Hoyte wrote:
>
>
>>> Conventions do have their use.
>> 
>> I agree, I just personally don't think this one is necessary.
>>
>
> I think it's pretty much necessary in _CL_, but I do sometimes wish 
> special variables were neatly separated from lexical variables, like
> islisp with its defdynamic/dynamic-let/dynamic

Your wish is CL's command:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun dynvar (name) (intern (format nil "*~A*" name)
                               (symbol-package name))))

(defmacro defdynamic (name form) 
  `(progn (defvar ,(dynvar name) ,form)
          ',name))
(defmacro dynamic-let (bindings &body body)
   `(let ,(mapcar (lambda (binding)
                      (destructuring-bind (var form) binding
                        `(,(dynvar var) ,form)))
                  bindings)
        ,@body))
(defmacro dynamic (name) (dynvar name))
(defmacro set-dynamic (name form) `(setf ,(dynvar name) ,form))


But please, note how the ISO Lisp standard itself uses the stars in
its examples of dynamic variable (cf. page 25 of ISO/IEC 13816:1997(E)).


C/USER[112]> (defdynamic *color* 'red)
*COLOR*
C/USER[113]> (dynamic *color*)
RED
C/USER[114]> (defun what-color () (dynamic *color*))
WHAT-COLOR
C/USER[115]> (dynamic-let ((*color* 'green)) (what-color))
GREEN
C/USER[116]> (dynamic package)
#<PACKAGE COMMON-LISP-USER>

> Of course there could have been read syntax for (dynamic blah) like
> #'blah is read syntax for (function blah) e.g. *blah

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: Pascal Costanza
Subject: Re: Let Over Lambda chapter 4
Date: 
Message-ID: <6cm8fjF3g3o2pU1@mid.individual.net>
Doug Hoyte wrote:
> On Jun 27, 8:31 pm, Rainer Joswig <······@lisp.de> wrote:
> 
> Hi Rainer,
> 
> Thanks for your comments.
> 
>> * DEFsomething or DEFINE-SOMETHING
>> * doING
>> * DOsomething
> 
>>> Would you use this convention? No, of course you wouldn't.
> 
>> I already use the with- convention.
> 
> Sorry I think there was some confusion. I myself like and use
> all the conventions you mentioned above. I was only suggesting
> that conventions shouldn't supersede proper naming of functions,
> macros, or variables. Because with-open-file is named well, it
> is easy to remember it is a macro.
> 
> I also understand why people like the earmuffs and have nothing
> against their use. I was just trying to explain why I don't
> use them.

...but as a book author you have a responsibility that goes beyond what 
you personally like and don't like...

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/