Are there any ways to manipulate symbols analogously to what can be
done with strings? I mean, for instance, is it possible to concatenate
two symbols like 'my and 'sum into 'mysum like you can with strings as
follows?
(concatenate 'string "my" "sum")
I know for example that a string can be converted to a symbol with the
"intern" function (though I've discovered through using it, that
you've really got to be careful with case!) But I'm not aware of any
particular way of operating directly on the symbols.
Thank you.
On Mar 26, 9:17 pm, ···········@gmail.com wrote:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings? I mean, for instance, is it possible to concatenate
> two symbols like 'my and 'sum into 'mysum like you can with strings as
> follows?
>
> (concatenate 'string "my" "sum")
>
> I know for example that a string can be converted to a symbol with the
> "intern" function (though I've discovered through using it, that
> you've really got to be careful with case!) But I'm not aware of any
> particular way of operating directly on the symbols.
>
> Thank you.
You can get the (string) name of a symbol using SYMBOL-NAME. So for
your example the code would be
(intern (concatenate 'string (symbol-name 'my) (symbol-name 'sum)))
Michael
On Mar 26, 8:46 pm, Michael Ben-Yosef <········@mweb.co.za> wrote:
> On Mar 26, 9:17 pm, ···········@gmail.com wrote:
>
> > Are there any ways to manipulate symbols analogously to what can be
> > done with strings? I mean, for instance, is it possible to concatenate
> > two symbols like 'my and 'sum into 'mysum like you can with strings as
> > follows?
>
> > (concatenate 'string "my" "sum")
>
> > I know for example that a string can be converted to a symbol with the
> > "intern" function (though I've discovered through using it, that
> > you've really got to be careful with case!) But I'm not aware of any
> > particular way of operating directly on the symbols.
>
> > Thank you.
>
> You can get the (string) name of a symbol using SYMBOL-NAME. So for
> your example the code would be
> (intern (concatenate 'string (symbol-name 'my) (symbol-name 'sum)))
>
> Michael
Thanks Michael. So it seems I do have to do some coverting though
after all.
> Thanks Michael. So it seems I do have to do some coverting though
> after all.
The point of interned symbols is that their names as strings are no
longer required to determine their identity as objects. For example,
to check if two interned symbols are equal, Lisp doesn't need to
compare their names as strings. Hence the name of a symbol is really
just one of it's properties as an object. (See the definition for the
SYMBOL class, here: http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm
) Two different symbols can have the same name if they are interned in
different packages (or uninterned), for example 'CL:DEFUN and :DEFUN
both have the name "DEFUN".
What I'm getting at is that symbols may not be the right kind of
objects to use if you want to do a lot of slicing, dicing and splicing
with their names. You probably want to stick to strings until you have
one you really need to intern as a symbol. In any case, as Xach
pointed out, in many functions you can use a symbol in place of its
name.
Michael
Michael Ben-Yosef <········@mweb.co.za> writes:
> On Mar 26, 9:17 pm, ···········@gmail.com wrote:
> > Are there any ways to manipulate symbols analogously to what can be
> > done with strings? I mean, for instance, is it possible to concatenate
> > two symbols like 'my and 'sum into 'mysum like you can with strings as
> > follows?
> >
> > (concatenate 'string "my" "sum")
> >
> > I know for example that a string can be converted to a symbol with the
> > "intern" function (though I've discovered through using it, that
> > you've really got to be careful with case!) But I'm not aware of any
> > particular way of operating directly on the symbols.
> >
> > Thank you.
>
> You can get the (string) name of a symbol using SYMBOL-NAME. So for
> your example the code would be
> (intern (concatenate 'string (symbol-name 'my) (symbol-name 'sum)))
>
CL-USER> (eql (concatenate 'string "alan" "crowe")
(concatenate 'string "alan" "crowe"))
=> NIL
CL-USER> (eql (intern (concatenate 'string
(symbol-name 'alan)
(symbol-name 'crowe)))
(intern (concatenate 'string
(symbol-name 'alan)
(symbol-name 'crowe))))
=> T
Symbols are for when you want to trade to get fast identity
checks at the exense of a lack of internal structure. INTERN
uses a hash table to recognise strings that it has interned before.
Strings are for the opposite trade: easy to append and check
for substrings, but identity requires a character by
character comparison.
You know who
Edinburgh
Scotland
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: Strings and symbols
Date:
Message-ID: <rem-2008apr02-008@yahoo.com>
> From: Alan Crowe <····@cawtech.freeserve.co.uk>
> Symbols are for when you want to trade to get fast identity
> checks at the exense of a lack of internal structure. INTERN
> uses a hash table to recognise strings that it has interned before.
> Strings are for the opposite trade: easy to append and check
> for substrings, but identity requires a character by
> character comparison.
Let me say that in different words that IMO might be more clear:
Symbols are for where you will need lots of comparison at runtime,
so you want to invest some effort to canonicalize the textual names
so that all duplicates of the same string of characters will be
identical machine location, so that comparison then becomes
trivial. Symbols also have a lot of storage overhead to store
the value cell and the function cell and the properties cell as well
as the link from the main cell to the print-name cell. If you write
(setq x 5)
(setq y (+ x 3))
it's essential that the first x match the second x, so that the
second expression can see the value you assigned in the first
expression, so you use a symbol. If you tried to do it by strings,
the code would read something like this:
(setq $ht$ (make-hash-table :test #'equal))
(setf (get $ht$ "x") 5)
(setf (get $ht$ "y") (+ (get $ht$ "x") 3))
See how messy it is to register each new value of "x" in the hash
table then recover it later via another hashtable lookup?
And every time you enter a function and want to establish a lexical
context, you'd have to build a whole new hash table!!
And how would you pass parameters to a function without using
symbols as parameters?? Maybe you'd prefer Unix's argv convention,
using a hashtable for parameters to each function?
(defun arithemetical-mean (myht)
(return (/ (+ (get myht "1") (get myht "2"))
2)))
(let ((arght (make-hash-table :test #'equal)))
(setf (get arght "1") (get $ht$ "x1"))
(setf (get arght "2") (get $ht$ "x2"))
(setf (get $ht$ "y") (arithemetical-mean arght)))
Strings are for where you don't really care to find matches most of
the time, all you care is how the strings print out, so you aren't
willing to go to all the overhead of canonicalizing each string.
···········@gmail.com writes:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings? I mean, for instance, is it possible to concatenate
> two symbols like 'my and 'sum into 'mysum like you can with strings as
> follows?
Well, since a symbol is an object with various properties such as
associated values, functions (i.e., SYMBOL-VALUE, SYMBOL-FUNCTION), it
isn't immediately obvious what it would mean to concatenate such
objects. That is fundamentally why there isn't such a function.
If you want to concatenate only the SYMBOL-NAME of the symbols, then you
need to specify that.
> (concatenate 'string "my" "sum")
>
> I know for example that a string can be converted to a symbol with the
> "intern" function (though I've discovered through using it, that
> you've really got to be careful with case!) But I'm not aware of any
> particular way of operating directly on the symbols.
Well, that's because the results are a bit underspecified. By the way,
you can also use MAKE-SYMBOL, if you don't want the symbol to be
interned.
However, it isn't that hard to write your own function:
(defun symbol-concatenate (&rest symbols)
(intern (apply #'concatenate 'string (mapcar #'symbol-name symbols))))
or if you only need to do two symbols:
(defun symbol-concatenate2 (symbol1 symbol2)
(intern (concatenate 'string (string symbol1) (string symbol2))))
--
Thomas A. Russ, USC/Information Sciences Institute
On Mar 26, 10:16 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> ···········@gmail.com writes:
> > Are there any ways to manipulate symbols analogously to what can be
> > done with strings? I mean, for instance, is it possible to concatenate
> > two symbols like 'my and 'sum into 'mysum like you can with strings as
> > follows?
>
> Well, since a symbol is an object with various properties such as
> associated values, functions (i.e., SYMBOL-VALUE, SYMBOL-FUNCTION), it
> isn't immediately obvious what it would mean to concatenate such
> objects. That is fundamentally why there isn't such a function.
>
> If you want to concatenate only the SYMBOL-NAME of the symbols, then you
> need to specify that.
>
> > (concatenate 'string "my" "sum")
>
> > I know for example that a string can be converted to a symbol with the
> > "intern" function (though I've discovered through using it, that
> > you've really got to be careful with case!) But I'm not aware of any
> > particular way of operating directly on the symbols.
>
> Well, that's because the results are a bit underspecified. By the way,
> you can also use MAKE-SYMBOL, if you don't want the symbol to be
> interned.
>
> However, it isn't that hard to write your own function:
>
> (defun symbol-concatenate (&rest symbols)
> (intern (apply #'concatenate 'string (mapcar #'symbol-name symbols))))
>
> or if you only need to do two symbols:
>
> (defun symbol-concatenate2 (symbol1 symbol2)
> (intern (concatenate 'string (string symbol1) (string symbol2))))
>
> --
> Thomas A. Russ, USC/Information Sciences Institute
Thank you all for kindly helping me out with this issue. I realize it
appears to be a very strange thing someone would want to do :) but
strangely enough the need for it arose while I was working on a GUI
and I needed to automatically generate labels like button1, button2,
button3, and so on ... I could've done it by hand, but I thought to
myself "this is what Lisp is all about, being able to abstract certain
patterns out", so there should be some reasonable way of automagically
generating those labels, say with a loop over i, and concatenating
"button" with i, and thus "interning" the resulting symbol. Then, one
thing leads to another, I wondered if one could manipulate symbol
names (generating new symbols) like strings, and that's the reason for
this post :)
Thanks again.
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: Strings and symbols
Date:
Message-ID: <rem-2008mar27-002@yahoo.com>
> From: ···········@gmail.com
> I realize it appears to be a very strange thing someone would
> want to do :) but strangely enough the need for it arose while I
> was working on a GUI and I needed to automatically generate labels
> like button1, button2, button3, and so on ...
Normally the label on a button is a string. Why would you want it
to be a symbol instead? How could a symbol even work for that
purpose?
Here is Common Lisp evidence:
<http://kantz.com/jason/clim-primer/panes.htm>
(make-pane 'push-button :label "squeeze" :activate-callback #'squeeze)
(make-pane 'push-button :label "press" :activate-callback #'press)))
See, the label on each push-button is a string, not a symbol.
<http://osdir.com/ml/lisp.mcclim.cvs/2006-02/msg00005.html>
\CLIM{} comes with a set of predefined gadget panes. They consist of
push-button, toggle-button, slider, radio-box, text-field, text-editor
panes ready for use by the \CLIM{} application programmer. ...
(I cited that just so you'd know how push-button fit into larger picture.)
The same is true in Java, but perhaps more clearly documentated:
<http://java.sun.com/j2se/1.3/docs/api/java/awt/Button.html>
Constructor Summary
Button(String label)
Constructs a Button with the specified label.
Method Summary
String getLabel()
Gets the label of this button.
void setLabel(String label)
Sets the button's label to be the specified string.
<http://java.sun.com/j2se/1.3/docs/api/javax/swing/JButton.html>
Constructor Summary
JButton(String text)
Creates a button with text.
Hmm, it's called "text" instead of "label", sigh.
Methods inherited from class javax.swing.AbstractButton
<http://java.sun.com/j2se/1.3/docs/api/javax/swing/AbstractButton.html>
public String getLabel()
Deprecated. - Replaced by getText
Returns the label text.
public void setLabel(String label)
Deprecated. - Replaced by setText(text)
Sets the label text.
Likewise in C++:
<http://www.informit.com/articles/article.aspx?p=173413&seqNum=2&rll=1>
QPushButton *quitButton = new QPushButton("Quit", 0);
<http://www.daniweb.com/forums/thread77173.html>
QPushButto *hello = new QPushButton("This is a simple button");
/* Creates a new button with the label "Hello World". */
button = gtk_button_new_with_label ("Hello World");
<http://doc.trolltech.com/3.3/qpushbutton.html>
Public Members
* QPushButton ( const QString & text, QWidget * parent,
const char * name = 0 )
The QPushButton widget provides a command button.
The push button, or command button, is perhaps the most commonly used
widget in any graphical user interface. Push (click) a button to
command the computer to perform some action, or to answer a question.
Typical buttons are OK, Apply, Cancel, Close, Yes, No and Help.
A command button is rectangular and typically displays a text label
describing its action. An underlined character in the label (signified
by preceding it with an ampersand in the text) indicates an
accelerator key, e.g.
QPushButton *pb = new QPushButton( "&Download", this );
Push buttons can display a textual label or a pixmap, and optionally a
small icon. These can be set using the constructors and changed later
using setText(), setPixmap() and setIconSet(). ...
Important Inherited Members
* QString text () const
Returns the text shown on the button. See the "text" property for
details.
* virtual void setText ( const QString & )
Sets the text shown on the button. See the "text" property for
details.
So you see in CLIM, java.awt, javax.swing, and C++ Qt toolkit,
everywhere the textual label for a button is given as a string.
Where do you get the idea it should be a symbol instead of a string?
> there should be some reasonable way of automagically generating
> those labels, say with a loop over i, and concatenating "button"
> with i, and thus "interning" the resulting symbol.
Huh? You can't concatenate a string with an integer. Perhaps you
mean you want to convert the integer to its decimal representation
as a string, and then concatenate "button" with that decimal
representation string? But even if you did that, the result would
be a string, not a symbol, and "thus" is totally wrong because
concatenating doesn't do interning so it wouldn't "thus" intern the
string. If you wanted to convert the string to an interned symbol,
that would be an extra step *after* concatenating.
But there's no need to convert the integer i to a string and *then*
concatenate the string "button" in front of it. Do it all in one step:
(format NIL "button~A" i)
> Then, one thing leads to another, I wondered if one could
> manipulate symbol names (generating new symbols) like strings, ...
Symbol names *are* strings!! So manipulating symbol names isn't
*like* manipulating strings, it **is* manipulating strings!
But manipulating symbol names (i.e. strings) doesn't generate any
new symbols, it just generates new strings.
I suggest you go back to the documentation for whatever GUI you're
trying to generate buttons for, and read carefully what it requires
to be passed to it as the name of a button. If it requires passing
a symbol, and forbids passing a string, that would be very
surprising. If you believe it says that, quote that specification
from the documentation so that we can see if you are understanding
it correctly.
Robert Maas, see http://tinyurl.com/uh3t wrote:
> Constructor Summary
> Button(String label)
> Constructs a Button with the specified label.
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html#JButton(javax.swing.Icon)
public JButton(Icon icon)
Creates a button with an icon.
--
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
On Mar 27, 10:45 am, Frank Buss <····@frank-buss.de> wrote:
> Robert Maas, seehttp://tinyurl.com/uh3twrote:
>
> > Constructor Summary
> > Button(String label)
> > Constructs a Button with the specified label.
>
> http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html#JBut...)
>
> public JButton(Icon icon)
>
> Creates a button with an icon.
>
> --
> Frank Buss, ····@frank-buss.dehttp://www.frank-buss.de,http://www.it4-systems.de
I'm sorry, my fault. I didn't mean label, I meant identifier. I was
looking for a way to actually bind values to symbols being generated
automatically, like button1, button2, etc... but I meant variables,
not the text labels that go on the buttons.
···········@gmail.com writes:
> I'm sorry, my fault. I didn't mean label, I meant identifier. I was
> looking for a way to actually bind values to symbols being generated
> automatically, like button1, button2, etc... but I meant variables,
> not the text labels that go on the buttons.
Lisp has arrays now, and you can access them with integers just like in
FORTRAN and C and Java and BASIC and INTERCAL. I really don't know why
you would think about constructing your own pounding-device out of bits
of twine and bent shoehorns when a hammer is sitting *right* *there* on
the bench beside you. ;)
···········@gmail.com writes:
> I'm sorry, my fault. I didn't mean label, I meant identifier. I was
> looking for a way to actually bind values to symbols being generated
> automatically, like button1, button2, etc... but I meant variables,
> not the text labels that go on the buttons.
But the problem with binding values to generated symbols is that you
still have to keep track of which symbols are available, since you can't
put runtime-generated symbols into your own code.
So somehow, you have to keep track of the button1, button2 symbols. And
whatever data structure you use to keep track of those symbols can
instead be simply used to keep track of the values. You could, for
example, use a hashtable to map button names to values. Or p-lists, for
that matter, if you need to store more than one attribute.
--
Thomas A. Russ, USC/Information Sciences Institute
On Mar 28, 5:45 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> ···········@gmail.com writes:
> > I'm sorry, my fault. I didn't mean label, I meant identifier. I was
> > looking for a way to actually bind values to symbols being generated
> > automatically, like button1, button2, etc... but I meant variables,
> > not the text labels that go on the buttons.
>
> But the problem with binding values to generated symbols is that you
> still have to keep track of which symbols are available, since you can't
> put runtime-generated symbols into your own code.
>
> So somehow, you have to keep track of the button1, button2 symbols. And
> whatever data structure you use to keep track of those symbols can
> instead be simply used to keep track of the values. You could, for
> example, use a hashtable to map button names to values. Or p-lists, for
> that matter, if you need to store more than one attribute.
>
> --
> Thomas A. Russ, USC/Information Sciences Institute
Oh yes, absolutely. But, at this point, just for the sake of
understanding the mechanism and thus the specification as best we can,
I've come across the following in the hyperspec regarding the function
INTERN:
"It is implementation-dependent whether the string that becomes the
new symbol's name is the given string or a copy of it. Once a string
has been given as the string argument to intern in this situation
where a new symbol is created, the consequences are undefined if a
subsequent attempt is made to alter that string."
Does this mean that, to play it safe, the best way to assign a value
to a symbol converted from a string would be using COPY-SEQ as
follows?
(defparameter *name* "my-variable")
(setf (symbol-value (intern (copy-seq (string-upcase *name*)))) "Any
old value!")
···········@gmail.com writes:
> On Mar 28, 5:45 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
>> ···········@gmail.com writes:
>> > I'm sorry, my fault. I didn't mean label, I meant identifier. I was
>> > looking for a way to actually bind values to symbols being generated
>> > automatically, like button1, button2, etc... but I meant variables,
>> > not the text labels that go on the buttons.
>>
>> But the problem with binding values to generated symbols is that you
>> still have to keep track of which symbols are available, since you can't
>> put runtime-generated symbols into your own code.
>>
>> So somehow, you have to keep track of the button1, button2 symbols. And
>> whatever data structure you use to keep track of those symbols can
>> instead be simply used to keep track of the values. You could, for
>> example, use a hashtable to map button names to values. Or p-lists, for
>> that matter, if you need to store more than one attribute.
>>
>> --
>> Thomas A. Russ, USC/Information Sciences Institute
>
> Oh yes, absolutely. But, at this point, just for the sake of
> understanding the mechanism and thus the specification as best we can,
> I've come across the following in the hyperspec regarding the function
> INTERN:
>
> "It is implementation-dependent whether the string that becomes the
> new symbol's name is the given string or a copy of it. Once a string
> has been given as the string argument to intern in this situation
> where a new symbol is created, the consequences are undefined if a
> subsequent attempt is made to alter that string."
>
> Does this mean that, to play it safe, the best way to assign a value
> to a symbol converted from a string would be using COPY-SEQ as
> follows?
>
> (defparameter *name* "my-variable")
> (setf (symbol-value (intern (copy-seq (string-upcase *name*)))) "Any
> old value!")
Yes.
Well in this very case, no, since *name* is bound to a literal string,
that shouldn't be modified already in the first place.
But:
(ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
(self (symbol-value (intern name)) 'ragnagna)
name))
would be very bad.
Better to write:
(ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
(self (symbol-value (intern (copy-seq name))) 'ragnagna)
name))
On the other hand, there's no need for copy-seq in this case:
(ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
(self (symbol-value (intern name)) 'ragnagna)
'not-name))
In the case of functions like string-upcase that may or may not return
the argument, you could avoid copy-seq in some occasions:
(ndo-something-with (let ((name (make-string 3 :initial-element (if (zerop (random 2))
#\A #\a))))
(self (symbol-value (intern (let ((u (string-upcase name)))
(if (eq u name)
(copy-seq name)
u)))) 'ragnagna)
name))
--
__Pascal Bourguignon__ http://www.informatimago.com/
"Klingon function calls do not have "parameters" -- they have
"arguments" and they ALWAYS WIN THEM."
On Mar 29, 12:35 pm, Pascal Bourguignon <····@informatimago.com>
wrote:
> ···········@gmail.com writes:
> > On Mar 28, 5:45 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> >> ···········@gmail.com writes:
> >> > I'm sorry, my fault. I didn't mean label, I meant identifier. I was
> >> > looking for a way to actually bind values to symbols being generated
> >> > automatically, like button1, button2, etc... but I meant variables,
> >> > not the text labels that go on the buttons.
>
> >> But the problem with binding values to generated symbols is that you
> >> still have to keep track of which symbols are available, since you can't
> >> put runtime-generated symbols into your own code.
>
> >> So somehow, you have to keep track of the button1, button2 symbols. And
> >> whatever data structure you use to keep track of those symbols can
> >> instead be simply used to keep track of the values. You could, for
> >> example, use a hashtable to map button names to values. Or p-lists, for
> >> that matter, if you need to store more than one attribute.
>
> >> --
> >> Thomas A. Russ, USC/Information Sciences Institute
>
> > Oh yes, absolutely. But, at this point, just for the sake of
> > understanding the mechanism and thus the specification as best we can,
> > I've come across the following in the hyperspec regarding the function
> > INTERN:
>
> > "It is implementation-dependent whether the string that becomes the
> > new symbol's name is the given string or a copy of it. Once a string
> > has been given as the string argument to intern in this situation
> > where a new symbol is created, the consequences are undefined if a
> > subsequent attempt is made to alter that string."
>
> > Does this mean that, to play it safe, the best way to assign a value
> > to a symbol converted from a string would be using COPY-SEQ as
> > follows?
>
> > (defparameter *name* "my-variable")
> > (setf (symbol-value (intern (copy-seq (string-upcase *name*)))) "Any
> > old value!")
>
> Yes.
>
> Well in this very case, no, since *name* is bound to a literal string,
> that shouldn't be modified already in the first place.
>
> But:
>
> (ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
> (self (symbol-value (intern name)) 'ragnagna)
> name))
> would be very bad.
>
> Better to write:
>
> (ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
> (self (symbol-value (intern (copy-seq name))) 'ragnagna)
> name))
>
> On the other hand, there's no need for copy-seq in this case:
>
> (ndo-something-with (let ((name (make-string 3 :initial-element #\a)))
> (self (symbol-value (intern name)) 'ragnagna)
> 'not-name))
>
> In the case of functions like string-upcase that may or may not return
> the argument, you could avoid copy-seq in some occasions:
>
> (ndo-something-with (let ((name (make-string 3 :initial-element (if (zerop (random 2))
> #\A #\a))))
> (self (symbol-value (intern (let ((u (string-upcase name)))
> (if (eq u name)
> (copy-seq name)
> u)))) 'ragnagna)
> name))
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
>
> "Klingon function calls do not have "parameters" -- they have
> "arguments" and they ALWAYS WIN THEM."
OK, I actually thought that all that could be said on this topic, had
been already, but I did discover something which is of course probably
well known (but not to me unfortunately until now):
(eval (read-from-string "(format t \"Hello World!!!~%\")"))
READ-FROM-STRING can really do the job when it comes to passing from
strings to Lisp objects!
The only thing is that I didn't expect to find out that EVAL does not
"see" the lexically scoped environment in which it is operating. WHY
IS THAT? I'm really very curious. I tried some stuff, for instance, in
the Python language with its eval function, and the lexical scoping
was valid, so I can't figure out the reason for doing it differently
in Lisp.
···········@gmail.com writes:
> The only thing is that I didn't expect to find out that EVAL does not
> "see" the lexically scoped environment in which it is operating. WHY
> IS THAT? I'm really very curious. I tried some stuff, for instance, in
> the Python language with its eval function, and the lexical scoping
> was valid, so I can't figure out the reason for doing it differently
> in Lisp.
The reason is because Common Lisp is an industrial strong programming
language. It is designed with efficiency in mind (that's why some CL
compilers beat some C compilers). Compilation time of the lexical
environment occurs before evaluation time of the EVAL call, and CL
allows very optimized compilation of lexical environments. The name
of the variable, and even the variable themselves maybe optimized out,
may and will disappear from the generated code. When EVAL is called,
there is no more a lexical environment to be used, only processor
instructions doing references to the heap or the stack. Not a symbol
in sight.
(disassemble (compile nil (lambda (a b c)
(let ((d (- (* b b) (* 4 a c))))
(when (plusp d)
(eval '(+ 1 1)))))))
Disassembly of function NIL
(CONST 0) = 4
(CONST 1) = (+ 1 1)
3 required arguments
0 optional arguments
No rest parameter
No keyword parameters
16 byte-code instructions:
0 (LOAD&PUSH 2)
1 (LOAD&PUSH 3)
2 (CALLSR&PUSH 2 55) ; *
5 (CONST&PUSH 0) ; 4
6 (LOAD&PUSH 5)
7 (LOAD&PUSH 4)
8 (CALLSR&PUSH 3 55) ; *
11 (CALLSR&PUSH 1 54) ; -
14 (LOAD&PUSH 0)
15 (CALLS2 147) ; PLUSP
17 (JMPIFNOT1 L24)
19 (CONST&PUSH 1) ; (+ 1 1)
20 (CALLS1 91) ; EVAL
22 (SKIP&RET 5)
24 L24
24 (SKIP&RET 5)
NIL
C/USER[157]>
See? No D!
Note how the value (- (* b b) (* 4 a c)) is not even stored anywhere.
--
__Pascal Bourguignon__ http://www.informatimago.com/
This is a signature virus. Add me to your signature and help me to live.
Pascal Bourguignon wrote:
> The name of the variable, and even the variable themselves maybe
> optimized out, may and will disappear from the generated code. When
> EVAL is called, there is no more a lexical environment to be used,
> only processor instructions doing references to the heap or the
> stack. Not a symbol in sight.
Not to encourage use of eval, but just to note that while the name may
indeed be optimised away, you can of course choose
to _explicitly_ splice values from lexical variables into the lisp
expression to be eval'd if you really want to.
Sometimes I feel the whole "no lexical environment" thing is getting to
be a bit overstated - it's of course entirely true, but at the same
time, if you really want to inject a value into the expression to be
evalled you can, you just have to do it explicitly, and it doesn't
matter if that value happens to come from a lexical variable.
(disassemble (compile nil (lambda (a b c)
(let ((d (- (* b b) (* 4 a c))))
(when (plusp d)
(eval (list '+ d 1)))))))
Of course, this does not diminish the fact that usually, when if
you're using eval, chances are you probably shouldn't be...
On Apr 2, 4:51 am, David Golden <············@oceanfree.net> wrote:
> Pascal Bourguignon wrote:
> > The name of the variable, and even the variable themselves maybe
> > optimized out, may and will disappear from the generated code. When
> > EVAL is called, there is no more a lexical environment to be used,
> > only processor instructions doing references to the heap or the
> > stack. Not a symbol in sight.
>
> Not to encourage use of eval, but just to note that while the name may
> indeed be optimised away, you can of course choose
> to _explicitly_ splice values from lexical variables into the lisp
> expression to be eval'd if you really want to.
>
> Sometimes I feel the whole "no lexical environment" thing is getting to
> be a bit overstated - it's of course entirely true, but at the same
> time, if you really want to inject a value into the expression to be
> evalled you can, you just have to do it explicitly, and it doesn't
> matter if that value happens to come from a lexical variable.
>
> (disassemble (compile nil (lambda (a b c)
> (let ((d (- (* b b) (* 4 a c))))
> (when (plusp d)
> (eval (list '+ d 1)))))))
>
> Of course, this does not diminish the fact that usually, when if
> you're using eval, chances are you probably shouldn't be...
Thanks guys for clearing this up for me. David, to tell you the truth,
I had no intention of using EVAL actually, and I think that it's a
much better option to use macros practically all of the time, but,
still I was really curious to know why the difference between, say,
Python's choice of conserving lexical scoping for the eval function,
and Lisp's decision not to. Now, I understand perfectly. And thank you
for showing me that it is possible to "inject" values from the lexical
scope in eval anyway, using LIST (clever :) ).
···········@gmail.com wrote:
> Now, I understand perfectly. And thank you
> for showing me that it is possible to "inject" values from the lexical
> scope in eval anyway, using LIST (clever :) ).
Well, just pay close attention to Mark Wooding's reply re backquote and
self-evaluation too. If d had somehow been the list (- 7 4) say, it
would have been spliced in and evaluated as part of the expression, and
you might (wrong) or might not (right) have naively expected an error
since (- 7 4) is not a number, it's a list, though the result of its
standard evaluation is of course a number. In the obscure cases where
I've ever felt like doing this, I think the splice-evaluate is just
what I wanted anyway, but Mark is right too.
Just remember you're building up a whole expression and then evaluating
it, and it all makes sense, honest.
i.e.
(let ((d '(- 7 4)))
(eval (list '+ d 1)))
=> 4
because
(let ((d '(- 7 4)))
(list '+ d 1))
=> (+ (- 7 4) 1)
** vs
(let ((d '(- 7 4)))
(eval `(+ ',d 1)))
=> TYPE ERROR
because
(let ((d '(- 7 4)))
`(+ ',d 1))
=> (+ '(- 7 4) 1)
** but
(let ((d 3))
(eval `(+ ',d 1)))
=> 4
because
CL-USER> (let ((d 3))
`(+ ',d 1))
=> (+ '3 1)
(and '3 => 3)
David Golden <············@oceanfree.net> wrote:
> (disassemble (compile nil (lambda (a b c)
> (let ((d (- (* b b) (* 4 a c))))
> (when (plusp d)
> (eval (list '+ d 1)))))))
This only works if the value of d is self-evaluating. If your goal is
to handle the value of d within the eval, then you should probably write
it as
(eval `(+ ',d 1))
Compare:
(defun foo (thing)
(eval (list 'list ''before thing ''after)))
(foo '(error "this error is signalled."))
(defun bar (thing)
(eval `(list 'before ',thing 'after)))
(bar '(error "this form is just included in the output."))
-- [mdw]
···········@gmail.com writes:
> I've come across the following in the hyperspec regarding the function
> INTERN:
>
> "It is implementation-dependent whether the string that becomes the
> new symbol's name is the given string or a copy of it. Once a string
> has been given as the string argument to intern in this situation
> where a new symbol is created, the consequences are undefined if a
> subsequent attempt is made to alter that string."
>
> Does this mean that, to play it safe, the best way to assign a value
> to a symbol converted from a string would be using COPY-SEQ as
> follows?
Well, I think to play it safe, it would be best if you don't mutate your
strings, unless you have explicitly created them with MAKE-STRING to use
as buffers.
Mutating literal strings is non-conforming code anyway.
> (defparameter *name* "my-variable")
> (setf (symbol-value (intern (copy-seq (string-upcase *name*)))) "Any
> old value!")
Here, the value of *name* is a literal string, so you shouldn't ever try
doing (setf (char *name* 1) #\e) on it.
You would really only need to worry about using COPY-SEQ if you had some
buffer that you expected to be mutated that you were passing to INTERN.
--
Thomas A. Russ, USC/Information Sciences Institute
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: Strings and symbols
Date:
Message-ID: <rem-2008apr05-001@yahoo.com>
> From: ····@sevak.isi.edu (Thomas A. Russ)
> > I'm sorry, my fault. I didn't mean label, I meant identifier. I was
> > looking for a way to actually bind values to symbols being generated
> > automatically, like button1, button2, etc... but I meant variables,
> > not the text labels that go on the buttons.
(Belated but crucial clarification from OPoster about OProblem.)
> But the problem with binding values to generated symbols is that
> you still have to keep track of which symbols are available, since
> you can't put runtime-generated symbols into your own code.
Mostly correct. If symbols are generated at run time, in a way that
wasn't predictable at human-writes-sourcecode time nor even at
compile or load time, then then obviously the human-written source
code can't magically know what those not-yet-existant symbols will
be, hence can't make references to them by name even if they will
be interned after they are created at runtime.
But Lisp has the capability of computer-generated code, both in
macros which expand into executable (interal-form-of) source code,
where new symbols can be generated at load time or compile time
(whenever the macros are expanded), and also in "genuine"
general-purpose computer-generated source code which is generated
any time you want it to the executed via EVAL whenever later you
want it to. In both those cases, any context which generates a
block of code can generate symbols to be used as labels which can
be cross-linked between all the different parts of that code
generated from within that context. For example, in a GUI, a bunch
of symbols could be generated for the various widgets, all in a
single context, and each symbol could be bound to the corresponding
widget, and code could be generated to be executed when each widget
is manipulated in some particular way (such as by clicking or
sliding etc.), and that generated code for each manipulation of
each widget could make references to some other widgets, for
example clicking this widget causes that other widget to turn
bright red and recalculate its data. This sounds perhaps like what
the OPoster might have been wanting in his OQuestion.
So if you write code which when executed writes additional code,
obviously that first code is "your own code", but is it proper to
refer to that additional code also as "your own code"? If it's not
your own code, whose code is it??? So based on this quibble over
semantics of English, maybe runtime generated symbols can be used
in "your own code" or not.
> So somehow, you have to keep track of the button1, button2 symbols.
Correct, but only from when the symbols are generated through the
process of binding them to objects referring to them in other code
being generated for other objects at the same time and any other
uses you may ever have for those symbols, until finally you will
never again need to establish any additional links to those
symbols. So keeping track of the symbols could involve only a
purely local container.
Now you might want to do debugging on those symbols, like inspect
what their current value is, or replace the value with a new value
(a new piece of code), etc. So you might think a global hashtable
or package would be useful so that you could type in the name and
retrieve and/or modify the value. But since the names of the
symbols were randomly or sequentially generated at runtime, you
really don't *know* the names, so that would probably be of no
value. Better would be a way you can funny-click the actual widget
on-screen (right-click on two-button mouse such as on MS-Windows,
shift-click or option-click or control-click etc. on single-button
mouse such as on Macintosh) to invoke some debugging routine on
whatever symbol is associated with that widget. So back when you
had a temporary local container with all those runtime-generated
symbols, you needed to define a funny-click meaning for each
widget, which contained a reference to the corresponding
runtime-generated symbol. So you may never need even *see* the
print-names of those runtime-generated symbols much less remember
which is which and type back in the one you want to debug.
And if you want to change which widget is affected by clicking
another widget, you need visually see the relevant symbol
printnames and mentally keep track of them only briefly:
Funny-click on widget being affected to see its symbol name,
funny-click on widget you want to be affected to see its symbol
name and store it in a debug-temporary global for later recall,
funny-click on the controlling widget to see its machine-generated
source code, visually notice where the wrong affected-widget sits
in the code, edit that code to include instead the
correct-affected-widget symbol you saved earlier, and you're done.
With an object-oriented GUI source-code editor, you might be able
to click the correct-name right on the display then click the place
in the code where you want it to replace what's there, and you
don't even need the scratch-global explicitly. If you've used both
paint and drawing programs, where the paint program merely allows
copy&paste or move of sections of rendered image whereas the
drawing program has a hierarchial structure of the underlying
geometrical objects which can be cut/pasted/dragged, there's an
analogy here between a regular text editor which lets you edit the
print representation as strings of text vs. an object-oriented
data-structure editor which lets you directly manipulate the
underlying data structures. So if you copy an un-interned symbol
from one place to another, you really copy that symbol, not print
it out and paste in the textual name which then gives you a new
symbol by the same name. You want the *same* exact symbol, not one
by the same name.
> And whatever data structure you use to keep track of those
> symbols can instead be simply used to keep track of the values.
If you don't ever plan to debug the code within the runtime
environment, that may be an alternative design. But then every time
you ask the debugger to print out something that contains a network
of cross-links between several objects, with *never* a label to
demark the boundary from the code of one object to the code of
another object, you get a deeply circular list which requires the
circular-list prettyprinter, which assigns new temporary labels for
cross-references each time you print out the same haywire from a
different starting point, which can be utterly confusing. So having
names for all the major demarcation points may be utterly useful by
comparison.
I actually use this technique of demarcation names very commonly in
working with recursively-defined data structures that are defined
at runtime, which are just data, never executed as code, yet still
it's useful to have a stop-printer point at each juncture between
one object and each of its contained objects. For example, if I
want a demarcation name for a string (typically a very large string
containing the entire contents of a file) or a list (perhaps a very
large histogram, or maybe even a small list of standard format
where I just want to see the type and length when viewing something
larger that includes it as a part), I use this function:
(defun lensym-bind (val)
(prog (nam sym)
(setq nam
(cond ((stringp val) (format nil "S~D" (length val)))
((listp val) (format nil "L~D" (length val)))
(t (format nil "~A" (type-of val)))))
(setq sym (make-symbol nam))
(set sym val)
(return sym)
))
So then I might see some value as (:MYOBJ1 42 97.3 99.5 #:L7) and
if I really want to see what that L7 is I evaluate it to see
(:MYOBJ5 1 6 2 4 #:L5 #:L5) and if I really want to see what one of
those L5 is I evaluate it to see (:MYOBJ1 69 98.5 98.7 NIL) or
(:MYOBJ1 25 46.3 47.8 #:L7) etc. If I had an object-oriented GUI
data-structure editor, I could just click on whichever symbol I
want to evaluate to see one level deeper, but with just a REP here,
it's good enough to be able to say (symbol-value (nth 4 *)) etc.,
and if I do that a lot I can set up
(defun v (l n) (symbol-value (nth n l)))
to reduce my typing to (v * 4) or perhaps (v ** 4) if I did
something else in the mean time.
For your GUI application, something analagous might be useful,
which displays (in the print name) not the number of characters in
a string or number of elements in a list, but the widget type and
either sequential generation index (per the OP's statements,
Button1 Button2 Button3 TextField1 Button4 Radio1 Radio2 TextField2
CheckBox1 CheckBox2 etc.) or approximate y,x location on screen
(Button-0-1 Button-0-3 Button-0-7 TextField-1-0-9 Button-2-1 etc.),
depending on whether it's easier to remember the original sequence
of generating these widgets, or simply look at the screen (before
the window went invisible of course) and remember the row and
column number of the widget you want to debug.
> You could, for example, use a hashtable to map button names to
> values. Or p-lists, for that matter, if you need to store more
> than one attribute.
Would this be a global container for use by person debugging code
at runtime? Or a temporary local container only for purpose of
keeping track of the labels during the scope where all the
cross-linking would be set up?
If you mean a permanent global table: I'm thinking that if you can
set up funny-click actions on the widgets as entry points into
debugging or otherwise gronking a particular widget, that would be
better. But if you can't do that, then I agree having a master
table of widgets globally accessible would be useful. Also if a
widget is invisible, or maybe the whole window it's in is
invisible, then you can't funny-click a widget at that time, so the
global table of labels for widgets might be acceptable as a
work-around.
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: Strings and symbols
Date:
Message-ID: <rem-2008apr02-007@yahoo.com>
> From: ···········@gmail.com
> I'm sorry, my fault. I didn't mean label, I meant identifier. I
> was looking for a way to actually bind values to symbols being
> generated automatically, like button1, button2, etc... but I meant
> variables, not the text labels that go on the buttons.
Thanks for the correction so we can start solving the *actual*
problem you have instead of the mis-speak problem.
So you need to explain when such labels will first be built and how
long they will last and how many different parts of your system
will need to share knowledge of these symbols?
For example, is it necessary only to build these symbols at
runtime, and also at runtime to keep a list or hash table of these
symbols as well as pointers to inviduals which are passed around as
parameters and return values and deposited in semi-permanent places
within the runtime environment?
Is there any reason whatsoever that the user, at runtime, would
need to manually type in something representing one of these
symbols and thereby select something to happen to it? Or would all
selection of these symbols be via a menu, where direct links to the
symbols would be in the menu-object so no translation from type-in
to internal-object would need ever occur?
I suggest *very* strongly that you make a list of all use-cases
that in any way directly use these symbols, so that we can decide
what characteristics they require. If any use-case requires manual
type-in, not menu selection, then there must be a global list or
hashtable that would support lookup. Also if there's any function
that affects *all* these symbols, then again you need some kind of
global collection of them. Will it be possible to build an
unlimited number of new labels at runtime, and then generate code
that makes reference to these labels, which can then be EVALed?
All these kinds of use-case questions need to be answered before we
can make any further effort toward helping you. If we try to guess
what your use-cases are, we'll be wasting our time and yours.
Depending on use cases, the best design might be a special package
that has all these symbols, or just a simple hashtable of
uninterned symbols, or just an a-list of uninterned symbols, or no
global collection of them all whatsoever, or not symbols at all but
rather CLOS objects or just DEFSTRUCTs in some class you define
yourself.
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: Strings and symbols
Date:
Message-ID: <rem-2008apr02-006@yahoo.com>
> > Constructor Summary
> > Button(String label)
> > Constructs a Button with the specified label.
> From: Frank Buss <····@frank-buss.de>
> http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html#JButton(javax.swing.Icon)
> public JButton(Icon icon)
> Creates a button with an icon.
Correct, but irrelevant. The topic of discussion was whether
textual labels were symbols or strings, not whether other kinds of
labels can also be used. Clearly the OP was referring to the
print-name of the symbol, trying to concatenate those print-names,
not some other ICON property of a symbol and trying to concatenate
picture-icons together to make a larger icon. (And as it turned
out, what he *really* wanted was a symbol as a variable whose value
cell held a link to the widgit, which had nothing to do with a
label or icon displayed on the widget itself.)
Today we have US-ASCII characters in strings and print-names of
symbols and syntax of source code.
Tomorrow we'll have UniCode characters for the same use.
A Chinese adaption of Common Lisp might use single Chinese
characters for most of the common Lisp functions.
Maybe someday when our youngsters are dumbed down that they can't
read English or any other ordinary language, hence can't even begin
to understand program syntax, we'll need to devise a totally
icon-based graphical programming language with not a single
character of ordinary text like natural language anywhere.
It'd be almost like we took the picture icons that fill the top
rows above the edit area of a MS-Word window and used them as the
primitives of our langauge.
Or maybe China will revert their written language to the old form
that had actual pictures of stuff (like Egyption heirogliphics),
and all the youngers worldwide will recognize them as familiar
icons and all programming languages will switch to ancient-Chinese
icons?
···········@gmail.com writes:
> Thank you all for kindly helping me out with this issue. I realize it
> appears to be a very strange thing someone would want to do :) but
> strangely enough the need for it arose while I was working on a GUI
> and I needed to automatically generate labels like button1, button2,
> button3, and so on ...
Why didn't you say so in the first place?
(GENTEMP "BUTTON-")
By the way, is there any particular reason the labels need to be
symbols? Is that what the GUI library needs? Or do you use them as
keys?
--
Thomas A. Russ, USC/Information Sciences Institute
···········@gmail.com writes:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings? I mean, for instance, is it possible to concatenate
> two symbols like 'my and 'sum into 'mysum like you can with strings as
> follows?
>
> (concatenate 'string "my" "sum")
>
> I know for example that a string can be converted to a symbol with the
> "intern" function (though I've discovered through using it, that
> you've really got to be careful with case!) But I'm not aware of any
> particular way of operating directly on the symbols.
A symbol in CL is also a designator for the string that is its name;
see the full description here:
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#string_designator
This doesn't help in the CONCATENATE case, but many other
string-specific functions take string designators, and therefore
symbols, when it's convenient.
Zach
···········@gmail.com writes:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings?
Why do you want to do this?
--
Frode Vatvedt Fjeld
···········@gmail.com writes:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings? I mean, for instance, is it possible to concatenate
> two symbols like 'my and 'sum into 'mysum like you can with strings as
> follows?
>
> (concatenate 'string "my" "sum")
>
> I know for example that a string can be converted to a symbol with the
> "intern" function (though I've discovered through using it, that
> you've really got to be careful with case!) But I'm not aware of any
> particular way of operating directly on the symbols.
Well the classical way of processing symbols is to use EXPLODE and
IMPLODE:
(implode (append (explode 'my) (explode 'sum))) --> MYSUM
Unfortunately { ;-) } implode and explode didn't make it to Common
Lisp�, so you have to implement them yourself:
(defun explode (symbol)
(map 'list (lambda (ch) (intern (string ch))) (string symbol)))
(defun implode (list-of-one-char-symbols)
(intern (format nil "~{~A~}" list-of-one-char-symbols )))
But still the question remains, why you would want to do such a thing,
now that we have true strings in lisp?
�implode and explode existed in lisp at a time when there was no
character and no string types. Characters were represented as
one-character symbols and strings as symbols.
(explode 'mysum) --> (M Y S U M)
--
__Pascal Bourguignon__ http://www.informatimago.com/
Kitty like plastic.
Confuses for litter box.
Don't leave tarp around.
On Mar 26, 12:17 pm, ···········@gmail.com wrote:
> Are there any ways to manipulate symbols analogously to what can be
> done with strings?
Just a very general comment since others have replied in more detail:
It took years for the Lisp community to understand the difference
between symbols and strings. In the old days, there were just
symbols, and what you want to do would have seemed completely natural
to use symbols for -- not just because there was no alternative, but
also because there were built-in functions like EXPLODE and IMPLODE
and GCTWA (ha! who remembers GCTWA? besides Kent, that is) that people
used for just this kind of purpose.
But eventually people realized that a separate string type was a good
idea, and started adding it to implementations. And as people got
experience with it, I think a clearer sense of the difference started
to emerge.
In a nutshell: symbols are identifiers that stand for something else.
Strings, on the other hand, have no meaning beyond their contents.
This distinction, which might initially seem like hair-splitting, is
actually quite fundamental. The very nature of a symbol is that it's
useless if it occurs in only one place. Rather, it needs to be
defined in one place and referenced in at least one other place -- or
at the very least, there need to be two occurrences of it which refer
to the same thing. This is true whether it's a variable in a program,
or used in some other way.
For strings, on the other hand, their usefulness doesn't depend on
whether there are multiple occurrences. Consider error messages to be
shown to a user, or lines of text in an editor buffer. These strings
don't stand for anything beyond themselves, and so it doesn't matter
whether they're repeated anywhere else in the program or the data it
is manipulating.
(An aside: too bad that after the Lisp community spent a couple
decades figuring all this out, the Java designers went and forgot it
again. Java has optionally interned strings, which don't really know
whether they're strings or symbols.)
For the particular use you have in mind -- GUI buttons -- personally,
I would want to use both a string and a symbol. The string is what
would appear on the screen; the symbol would serve as the name of the
button for purposes of communication between the application and the
GUI framework. (For instance, this would let you change the displayed
label on the button without having to change all the places in your
code that respond to events on that button.) I don't know whether any
Lisp GUI frameworks work that way, though.
Ah yes, you're still wondering about GCTWA :) It stood for Garbage
Collect Truly Worthless Atoms. Since there were only symbols, the
results of all "string operations" were interned. This tended to
cause the relevant system hash table to fill up. GCTWA told Lisp to
discard all symbols with neither a function nor a value binding, nor a
nonnull plist... that is, all symbols that weren't being used to refer
to anything.
-- Scott