From: Marc Spitzer
Subject: intern question
Date: 
Message-ID: <slrna3hrtt.vif.marc@oscar.eng.cv.net>
I have a question about intern, here is the code:
(defun roman_string (roman)
  "Takes a string and convets it to a list and hands it off to chapter 4
roman numeral to decimal converter, exercise 6.8.4"
  (check-&-convert (mapcar #'intern
			   (mapcar  #'string
				    (coerce (string-upcase roman) 'list)))))

My question is intern doing anything evil in the namespaces, I have
read the hyperspec on the intern(11.2) function and on the pointer to
symbols as tokens(2.3.4) and I am just not sure what is going on.
Just where do the symbols go? While I am here any comments on the code
are welcome, what there is of it.

Thanks 

marc

From: Kaz Kylheku
Subject: Re: intern question
Date: 
Message-ID: <j57_7.7833$Gb1.1672841@news2.calgary.shaw.ca>
In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>I have a question about intern, here is the code:
>(defun roman_string (roman)
>  "Takes a string and convets it to a list and hands it off to chapter 4
>roman numeral to decimal converter, exercise 6.8.4"
>  (check-&-convert (mapcar #'intern
>			   (mapcar  #'string
>				    (coerce (string-upcase roman) 'list)))))
>
>My question is intern doing anything evil in the namespaces, I have
>read the hyperspec on the intern(11.2) function and on the pointer to
>symbols as tokens(2.3.4) and I am just not sure what is going on.
>Just where do the symbols go? 

Since you haven't specified a package argument in the calls to intern,
your interned symbols go into the current package. That's what it means
to intern a symbol: to enter the symbol into a package. The intern
function creates a new symbol and enters it into the specified package,
which becomes its home package; or if a symbol of that name already
exists in the package, it returns that object instead of creating a
new one.

Interning is what enables the reader to resolve multiple occurences of
the same symbol name to the same symbol object.
From: Marc Spitzer
Subject: Re: intern question
Date: 
Message-ID: <slrna3i285.vif.marc@oscar.eng.cv.net>
In article <······················@news2.calgary.shaw.ca>, Kaz Kylheku wrote:
> In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>>I have a question about intern, here is the code:
>>(defun roman_string (roman)
>>  "Takes a string and convets it to a list and hands it off to chapter 4
>>roman numeral to decimal converter, exercise 6.8.4"
>>  (check-&-convert (mapcar #'intern
>>			   (mapcar  #'string
>>				    (coerce (string-upcase roman) 'list)))))
>>
>>My question is intern doing anything evil in the namespaces, I have
>>read the hyperspec on the intern(11.2) function and on the pointer to
>>symbols as tokens(2.3.4) and I am just not sure what is going on.
>>Just where do the symbols go? 
> 
> Since you haven't specified a package argument in the calls to intern,
> your interned symbols go into the current package. That's what it means
> to intern a symbol: to enter the symbol into a package. The intern
> function creates a new symbol and enters it into the specified package,
> which becomes its home package; or if a symbol of that name already
> exists in the package, it returns that object instead of creating a
> new one.
> 
> Interning is what enables the reader to resolve multiple occurences of
> the same symbol name to the same symbol object.

I was just confused about what happened if I interned a symbol 
multple times.  Would I be creating some kind of "mess" that 
would caus me grief down the road?  Was my use of intern the 
start of a bad habit or ok?  From your explanation I see I was
ok.

Thanks 

marc
From: Kaz Kylheku
Subject: Re: intern question
Date: 
Message-ID: <i78_7.6265$0B1.1284221@news3.calgary.shaw.ca>
In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>In article <······················@news2.calgary.shaw.ca>, Kaz Kylheku wrote:
>> Interning is what enables the reader to resolve multiple occurences of
>> the same symbol name to the same symbol object.
>
>I was just confused about what happened if I interned a symbol 
>multple times. 

And that's exactly what interning is concerned with: that interning the
same name twice in the same package gives you the same object.

People hack this sort of thing in other languages.

For example, in the XWindow programming interface, you have these things
called atoms, which are symbols maintained on the X server.  The function
XInternAtom creates an atom, or returns an existing one.  One use is to
identify properties associated with windows.  By reducing string names to
atom identifiers, which are presumably just integers, you simplify a lot
of things. Comparing whether two atoms are the same one is just an integer
comparison---and that's really all you care about. Storing, passing and
returning atoms is equally simple.
From: Marc Spitzer
Subject: Re: intern question
Date: 
Message-ID: <slrna3i46a.vif.marc@oscar.eng.cv.net>
In article <······················@news3.calgary.shaw.ca>, Kaz Kylheku wrote:
> In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>>In article <······················@news2.calgary.shaw.ca>, Kaz Kylheku wrote:
>>> Interning is what enables the reader to resolve multiple occurences of
>>> the same symbol name to the same symbol object.
>>
>>I was just confused about what happened if I interned a symbol 
>>multple times. 
> 
> And that's exactly what interning is concerned with: that interning the
> same name twice in the same package gives you the same object.
> 
> People hack this sort of thing in other languages.
> 
> For example, in the XWindow programming interface, you have these things
> called atoms, which are symbols maintained on the X server.  The function
> XInternAtom creates an atom, or returns an existing one.  One use is to
> identify properties associated with windows.  By reducing string names to
> atom identifiers, which are presumably just integers, you simplify a lot
> of things. Comparing whether two atoms are the same one is just an integer
> comparison---and that's really all you care about. Storing, passing and
> returning atoms is equally simple.

That cleared it up, thanks.  Time to start on 6.8.3.  One thing I can
say is that it is a lot of fun to learn CL and I look foward to 
working with it.  And that most of the people in this news group
contribute to that.  


Thanks again

marc
From: Kent M Pitman
Subject: Re: intern question
Date: 
Message-ID: <sfw1yh250g2.fsf@shell01.TheWorld.com>
····@oscar.eng.cv.net (Marc Spitzer) writes:

> I was just confused about what happened if I interned a symbol 
> multple times.

INTERN's whole job is to always return the same object given the 
same arguments, so calling it more than once is less of a big deal
than calling it the first time (which will create symbol).  [Of
course, just because it's your first call doesn't mean the symbol
wasn't created prior by someone else.]

> Would I be creating some kind of "mess" that 
> would caus me grief down the road?

Not through repeated calls.  Sometimes you create clutter by the first
call.  But the real issues of substantially more concern are:

 (a) You are effectively doing a hash table lookup on a string index,
     which isn't super-fast.  Most operations you want to do on 
     characters are a LOT faster if you just leave them as characters.
     I haven't seen what that other function does so can't say for sure,
     but odds are that all those calls to INTERN slow the whole program 
     down by a noticeable amount.  Maybe not slower "algorithmically",
     but still by a "gratuitous constant factor".

 (b) Symbols are packaged.  You should use packaged symbols when you need
     namespace partitioning and not otherwise.  If you don't need packages,
     you risk creating the symbol in a different package than it will be 
     used in and having it not be recognized, or you risk putting data on
     the plist or in a value or function cell, only to find it's not there
     when you look in some lookalike symbol from another package.  At the
     MIT Lab for Computer Science, we used to call this "package dyslexia".

> Was my use of intern the start of a bad habit or ok?

The use of any operator you don't really understand for a purpose you're
not sure of is a bad habit.  INTERN itself has good and bad uses, but if
you want to play the odds, I'd say for now you should assume you're more
likely to misuse it than to use it correctly ESPECIALLY if you are using it
in anything other than bootstrap code for your system that is intended to
assemble a package from spare parts... Even then, MOST such uses are better
done by DEFPACKAGE.  I'd say, as a novice, you have about a .1% chance of
actually needing INTERN in a real program and 99.9% chance of being doing
the wrong thing.  Once you are enough sophisticated to really understand
what it does, you might be more likely to devise uses for it because that's
what anyone does when they really understand an operator.. it becomes part
of their arsenal and they see uses for it where they didn't before.  But
that kind of use comes of understanding, and is not your first line of
attack at this point.

> From your explanation I see I was ok.

"Hmmmm."

(There was a program at the MIT AI Lab long ago called Wumpus that was a
logic-teaching game.  There was another program called the Wumpus Advisor
that used to watch people play and suggest hints when it thought they
had something to use.  Once in a while, rather than a hint, it would just
say "Hmmmm."  I always used to wonder what that meant.)
From: Thomas F. Burdick
Subject: Re: intern question
Date: 
Message-ID: <xcvwuyuklwt.fsf@conquest.OCF.Berkeley.EDU>
Kent M Pitman <······@world.std.com> writes:

> ····@oscar.eng.cv.net (Marc Spitzer) writes:
>
> > Would I be creating some kind of "mess" that 
> > would caus me grief down the road?
> 
> Not through repeated calls.  Sometimes you create clutter by the first
> call.  But the real issues of substantially more concern are:
> 
>  (a) You are effectively doing a hash table lookup on a string index,
>      which isn't super-fast.  Most operations you want to do on 
>      characters are a LOT faster if you just leave them as characters.
>      I haven't seen what that other function does so can't say for sure,
>      but odds are that all those calls to INTERN slow the whole program 
>      down by a noticeable amount.  Maybe not slower "algorithmically",
>      but still by a "gratuitous constant factor".

(with-picking (:nits t)
  It seems strange to me that people say things like "slower
  algorithmically" in cases like this, rather than "increased
  complexity", because that's exactly what you mean here.  People who
  analyze algorithms don't just consider things in big-O notation,
  but in detail -- all those constant factors are spelled out
  explicitly.  Which is part of why algorithm analysis is interesting
  to me, because different members of the same family of algorithms,
  which all have the same big-O complexity, can vary by 30% or 50% in
  their actual efficiency.  I know you were using common usage, the
  common usage just seems rather inverted to me.)

>  (b) Symbols are packaged.  You should use packaged symbols when you need
>      namespace partitioning and not otherwise.  If you don't need packages,
>      you risk creating the symbol in a different package than it will be 
>      used in and having it not be recognized, or you risk putting data on
>      the plist or in a value or function cell, only to find it's not there
>      when you look in some lookalike symbol from another package.  At the
>      MIT Lab for Computer Science, we used to call this "package dyslexia".

Interning characters from a string is almost always the wrong thing to
do.  In this case, since the string is raw input to something that
deals with symbols, he needs some sort of string->list-of-symbols
path.  Personally, I'd reccomend something like:

  (ecase char
    ((#\i #\I) :i)
    ((#\v #\V) :v))

> > Was my use of intern the start of a bad habit or ok?

In situations like this, probably.  Using the above approach, though,
will put you in a good habit of checking your input for sanity, and
not creating unnecessary symbols willy-nilly (if, say, your input was
"WJiv").

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Thomas A. Russ
Subject: Re: intern question
Date: 
Message-ID: <ymiu1txmzei.fsf@sevak.isi.edu>
Kent M Pitman <······@world.std.com> writes:

> 
> ····@oscar.eng.cv.net (Marc Spitzer) writes:
> 
> > I was just confused about what happened if I interned a symbol 
> > multple times.
> 
>  (a) You are effectively doing a hash table lookup on a string index,
>      which isn't super-fast.  Most operations you want to do on 
>      characters are a LOT faster if you just leave them as characters.

I would agree that this would certainly be a reasonable solution, as
long as the original poster has control over the implementation of the
roman numeral to decimal conversion function.  In that case, having it
work on lists of characters rather than lists of symbols with single
character names would be more efficient.

>      I haven't seen what that other function does so can't say for sure,
>      but odds are that all those calls to INTERN slow the whole program 
>      down by a noticeable amount.  Maybe not slower "algorithmically",
>      but still by a "gratuitous constant factor".

On the other hand, if the conversion function is to be treated as a
black box, there needs to be some way of going from the characters in
the string input to the symbols needed for the conversion routine.

INTERN would be a straightforward way of doing this, although one could
imagine other solutions such as using a hashtable with character keys or
even a case or ecase statement in a function call to do that mapping.

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: David Combs
Subject: Re: intern question
Date: 
Message-ID: <a238g4$fac$1@news.panix.com>
In article <···············@shell01.TheWorld.com>,
Kent M Pitman  <······@world.std.com> wrote:
>...
>(There was a program at the MIT AI Lab long ago called Wumpus that was a
>logic-teaching game.  There was another program called the Wumpus Advisor
>that used to watch people play and suggest hints when it thought they
>had something to use.  Once in a while, rather than a hint, it would just
>say "Hmmmm."  I always used to wonder what that meant.)

Do I smell a wumpus?

(From way back when, on Dec 20, twenex -- which had features
seemingly still unimplemented these days:  CONNECT and ADVISE,
both incredibly cool for product-support uses.)

David
From: Kent M Pitman
Subject: Re: intern question
Date: 
Message-ID: <sfwell33p5t.fsf@shell01.TheWorld.com>
····@oscar.eng.cv.net (Marc Spitzer) writes:

> I have a question about intern, here is the code:
> (defun roman_string (roman)
>   "Takes a string and convets it to a list and hands it off to chapter 4
> roman numeral to decimal converter, exercise 6.8.4"
>   (check-&-convert (mapcar #'intern
> 			   (mapcar  #'string
> 				    (coerce (string-upcase roman) 'list)))))
> 
> My question is intern doing anything evil in the namespaces, I have
> read the hyperspec on the intern(11.2) function and on the pointer to
> symbols as tokens(2.3.4) and I am just not sure what is going on.
> Just where do the symbols go? While I am here any comments on the code
> are welcome, what there is of it.

You don't say what check-&-convert does.

As to the question of "evil", INTERN is really not either conceptually or
computationally something you really want to be doing a lot of at runtime
in a program.  And certainly INTERN does its job in the current package,
which will be picked up from the dynamic environment, making your program
unreliable if you don't intend to advertise to the caller that they have
to assure *package* has an appropriate value.

Finally, you don't say what you are really trying to _do_, so it's hard to
evaluate whether this is the right way to do it.  But almost all programs
that try to intern individual characters out of a string's name are bad
ways of writing stuff...
From: Marc Spitzer
Subject: Re: intern question
Date: 
Message-ID: <slrna3i30j.vif.marc@oscar.eng.cv.net>
In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
> ····@oscar.eng.cv.net (Marc Spitzer) writes:
> 
>> I have a question about intern, here is the code:
>> (defun roman_string (roman)
>>   "Takes a string and convets it to a list and hands it off to chapter 4
>> roman numeral to decimal converter, exercise 6.8.4"
>>   (check-&-convert (mapcar #'intern
>> 			   (mapcar  #'string
>> 				    (coerce (string-upcase roman) 'list)))))
>> 
>> My question is intern doing anything evil in the namespaces, I have
>> read the hyperspec on the intern(11.2) function and on the pointer to
>> symbols as tokens(2.3.4) and I am just not sure what is going on.
>> Just where do the symbols go? While I am here any comments on the code
>> are welcome, what there is of it.
> 
> You don't say what check-&-convert does.

Sorry about that.  It takes a list of symbols, ex '(C L V I I) 
check to see it is a valid roman numeral and converts it to it's
decimal equivalent.  Here is the message with the code posted in it:

Message-ID: <····················@oscar.eng.cv.net>

> 
> As to the question of "evil", INTERN is really not either conceptually or
> computationally something you really want to be doing a lot of at runtime
> in a program.  And certainly INTERN does its job in the current package,
> which will be picked up from the dynamic environment, making your program
> unreliable if you don't intend to advertise to the caller that they have
> to assure *package* has an appropriate value.
> 
> Finally, you don't say what you are really trying to _do_, so it's hard to
> evaluate whether this is the right way to do it.  But almost all programs
> that try to intern individual characters out of a string's name are bad
> ways of writing stuff...

I was afraid it was not my best work, how would I make it better?  Using
the reader to read from a stream would have been better but I have not
gotten that far in the book, next chapter.  Anything else I missed?

Thank you

marc
From: Kaz Kylheku
Subject: Re: intern question
Date: 
Message-ID: <Ok8_7.6871$sb.1267315@news1.calgary.shaw.ca>
In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
>> ····@oscar.eng.cv.net (Marc Spitzer) writes:
>> 
>>> I have a question about intern, here is the code:
>>> (defun roman_string (roman)
>>>   "Takes a string and convets it to a list and hands it off to chapter 4
>>> roman numeral to decimal converter, exercise 6.8.4"
>>>   (check-&-convert (mapcar #'intern
>>> 			   (mapcar  #'string
>>> 				    (coerce (string-upcase roman) 'list)))))
>>> 
>>> My question is intern doing anything evil in the namespaces, I have
>>> read the hyperspec on the intern(11.2) function and on the pointer to
>>> symbols as tokens(2.3.4) and I am just not sure what is going on.
>>> Just where do the symbols go? While I am here any comments on the code
>>> are welcome, what there is of it.
>> 
>> You don't say what check-&-convert does.
>
>Sorry about that.  It takes a list of symbols, ex '(C L V I I) 
>check to see it is a valid roman numeral and converts it to it's
>decimal equivalent.  Here is the message with the code posted in it:

One way to do that might simply be to predefine all these symbols in your
roman computation package, and export them. Then a valid roman numeral is
simply a symbol that is EQ to one of the roman numeral symbols exported
by your package, and the package users understand that. So when some
argument is expected to be a roman numeral, they pass you one of these
objects.

In other words, you don't need explicit calls to intern, or to deal
with unravelling the spelling of a symbol's name. The name is relevant
only when objects are being read from their text representation in
a stream or string, or when objects are being formatted back to text.
As an object, you don't think of the symbol V as being the letter V,
that is just the object's name.
From: Marc Spitzer
Subject: Re: intern question
Date: 
Message-ID: <slrna3i5u3.vif.marc@oscar.eng.cv.net>
In article <·····················@news1.calgary.shaw.ca>, Kaz Kylheku wrote:
> In article <···················@oscar.eng.cv.net>, Marc Spitzer wrote:
>>In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
>>> ····@oscar.eng.cv.net (Marc Spitzer) writes:
>>> 
>>>> I have a question about intern, here is the code:
>>>> (defun roman_string (roman)
>>>>   "Takes a string and convets it to a list and hands it off to chapter 4
>>>> roman numeral to decimal converter, exercise 6.8.4"
>>>>   (check-&-convert (mapcar #'intern
>>>> 			   (mapcar  #'string
>>>> 				    (coerce (string-upcase roman) 'list)))))
>>>> 
>>>> My question is intern doing anything evil in the namespaces, I have
>>>> read the hyperspec on the intern(11.2) function and on the pointer to
>>>> symbols as tokens(2.3.4) and I am just not sure what is going on.
>>>> Just where do the symbols go? While I am here any comments on the code
>>>> are welcome, what there is of it.
>>> 
>>> You don't say what check-&-convert does.
>>
>>Sorry about that.  It takes a list of symbols, ex '(C L V I I) 
>>check to see it is a valid roman numeral and converts it to it's
>>decimal equivalent.  Here is the message with the code posted in it:
> 
> One way to do that might simply be to predefine all these symbols in your
> roman computation package, and export them. Then a valid roman numeral is
> simply a symbol that is EQ to one of the roman numeral symbols exported
> by your package, and the package users understand that. So when some
> argument is expected to be a roman numeral, they pass you one of these
> objects.
> 
> In other words, you don't need explicit calls to intern, or to deal
> with unravelling the spelling of a symbol's name. The name is relevant
> only when objects are being read from their text representation in
> a stream or string, or when objects are being formatted back to text.
> As an object, you don't think of the symbol V as being the letter V,
> that is just the object's name.

This is much later on in the book and I will revisit this post when 
I get there and can undersand the points raised well enough to 
comment on them.  

Thanks 

marc