From: Lars
Subject: question about symbols/keywords
Date: 
Message-ID: <edc7fb$f47$1@info.service.rug.nl>
Hello,

I'm currently trying to learn Common Lisp, and I have a question 
pertaining to keyword symbols: I noted that ::= prints as :=, and (EQ 
::= :=) is T. Finding this rather surprising, I tried :::= and got a 
READ error. Can someone please explain what the rule for colons in 
symbol names is?

Regards,
Lars

From: Pascal Costanza
Subject: Re: question about symbols/keywords
Date: 
Message-ID: <4ltopiF3j316U1@individual.net>
Lars wrote:
> Hello,
> 
> I'm currently trying to learn Common Lisp, and I have a question 
> pertaining to keyword symbols: I noted that ::= prints as :=, and (EQ 
> ::= :=) is T. Finding this rather surprising, I tried :::= and got a 
> READ error. Can someone please explain what the rule for colons in 
> symbol names is?

In Common Lisp, the colon is used as a package marker. The package 
system is a kind of module system, and package:name is a way to access a 
name in some package - note the use of the colon between "package" and 
"name".

What you accidentally stumbled upon are the exceptional rules for what 
happens when a token starts with a package marker. You can find the 
detailed rules for tokens and package markers at 
http://www.lispworks.com/documentation/HyperSpec/Body/02_ce.htm


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: Pascal Bourguignon
Subject: Re: question about symbols/keywords
Date: 
Message-ID: <87pseep6p1.fsf@thalassa.informatimago.com>
Lars <··@spam.please> writes:

> Hello,
>
> I'm currently trying to learn Common Lisp, and I have a question
> pertaining to keyword symbols: I noted that ::= prints as :=, and (EQ
> ::= :=) is T. Finding this rather surprising, I tried :::= and got a
> READ error. Can someone please explain what the rule for colons in
> symbol names is?

::= is scanned as:     ::   double package-marker
                       =    symbol named "="

:=  is scanned as:     :    package-marker
                       =    symbol named "="

As you have noted,

:::= is a lexical error, there's no triple package-marker.


Since a package name lacks, the package where a symbol named "=" is
interned is the KEYWORD package.

:=  has the same form as :EXTERNAL-FORMAT or :TEST

Now, the difference between : and :: is that :: will allow you to
access all the symbols that are interned in the corresponding package,
while : will allow you to access only the symbols that are _exported_
from that package.


The KEYWORD package is special, since all the symbols interned in this
package are:

   - automatically exported,
   - automatically defined as a constant having themselves as value:

(intern "NAME" "KEYWORD") ==> (defconstant KEYWORD::NAME 'KEYWORD::NAME)
                              (export 'KEYWORD::NAME)
in addition to the normal interning.


Otherwise, you will always have (EQ 'PACKAGE:SYMBOL 'PACKAGE::SYMBOL)
when the SYMBOL is exported from the PACKAGE.

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

ADVISORY: There is an extremely small but nonzero chance that,
through a process known as "tunneling," this product may
spontaneously disappear from its present location and reappear at
any random place in the universe, including your neighbor's
domicile. The manufacturer will not be responsible for any damages
or inconveniences that may result.
From: Lars
Subject: Re: question about symbols/keywords
Date: 
Message-ID: <edcgjr$hkn$1@info.service.rug.nl>
Pascal Bourguignon wrote:
> ::= is scanned as:     ::   double package-marker
>                        =    symbol named "="
> 
> :=  is scanned as:     :    package-marker
>                        =    symbol named "="
> 
> As you have noted,
> 
> :::= is a lexical error, there's no triple package-marker.
> 
> 
> Since a package name lacks, the package where a symbol named "=" is
> interned is the KEYWORD package.
> 
> :=  has the same form as :EXTERNAL-FORMAT or :TEST
> 
> Now, the difference between : and :: is that :: will allow you to
> access all the symbols that are interned in the corresponding package,
> while : will allow you to access only the symbols that are _exported_
> from that package.
> 
> 
> The KEYWORD package is special, since all the symbols interned in this
> package are:
> 
>    - automatically exported,
>    - automatically defined as a constant having themselves as value:
> 
> (intern "NAME" "KEYWORD") ==> (defconstant KEYWORD::NAME 'KEYWORD::NAME)
>                               (export 'KEYWORD::NAME)
> in addition to the normal interning.
> 
> 
> Otherwise, you will always have (EQ 'PACKAGE:SYMBOL 'PACKAGE::SYMBOL)
> when the SYMBOL is exported from the PACKAGE.

Aha, thanks! I'll consider using some other marker for BNF rules :)
From: Pascal Bourguignon
Subject: Re: question about symbols/keywords
Date: 
Message-ID: <873bbaothz.fsf@thalassa.informatimago.com>
Lars <··@spam.please> writes:

> Pascal Bourguignon wrote:
>> ::= is scanned as:     ::   double package-marker
>>                        =    symbol named "="
>> :=  is scanned as:     :    package-marker
>>                        =    symbol named "="
>> As you have noted,
>> :::= is a lexical error, there's no triple package-marker.
>> Since a package name lacks, the package where a symbol named "=" is
>> interned is the KEYWORD package.
>> :=  has the same form as :EXTERNAL-FORMAT or :TEST
>> Now, the difference between : and :: is that :: will allow you to
>> access all the symbols that are interned in the corresponding package,
>> while : will allow you to access only the symbols that are _exported_
>> from that package.
>> The KEYWORD package is special, since all the symbols interned in
>> this
>> package are:
>>    - automatically exported,
>>    - automatically defined as a constant having themselves as value:
>> (intern "NAME" "KEYWORD") ==> (defconstant KEYWORD::NAME
>> KEYWORD::NAME)
>>                               (export 'KEYWORD::NAME)
>> in addition to the normal interning.
>> Otherwise, you will always have (EQ 'PACKAGE:SYMBOL
>> PACKAGE::SYMBOL)
>> when the SYMBOL is exported from the PACKAGE.
>
> Aha, thanks! I'll consider using some other marker for BNF rules :)

You can use:
                \:=    |:=|
                \:\:=  |::=|

or if you don't need to distinguish between := and ::=, there's no
harm in using the keyword named "=": 

                :=

That said, pure BNF (or EBNF perhaps), also use | and . which can be
hard to read with the lisp reader too, so either you implement your
own BNF reader, or you can lispify the syntax entirely.

Both:

  (read-ebnf "sexp-list := sexp | sexp sexp-list .")
  (read-from-string "(--> sexp-list (alt sexp (seq sexp sexp-list)))")

can produce the same result:

  (--> sexp-list (alt sexp (seq sexp sexp-list)))



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

"Logiciels libres : nourris au code source sans farine animale."