Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Re: Strings and symbols
rocco.rossi@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.

Report this thread to moderator Post Follow-up to this message
Old Post
Pascal Bourguignon
04-02-08 03:40 AM


Re: Strings and symbols
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...




Report this thread to moderator Post Follow-up to this message
Old Post
David Golden
04-02-08 03:40 AM


Re: Strings and symbols
On Apr 2, 4:51 am, David Golden <david.gol...@oceanfree.net> wrote:
> Pascal Bourguignon wrote: 
>
> 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 :) ).

Report this thread to moderator Post Follow-up to this message
Old Post
rocco.rossi@gmail.com
04-02-08 09:47 AM


Re: Strings and symbols
David Golden <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]

Report this thread to moderator Post Follow-up to this message
Old Post
Mark Wooding
04-02-08 01:30 PM


Re: Strings and symbols
rocco.rossi@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)
















Report this thread to moderator Post Follow-up to this message
Old Post
David Golden
04-03-08 12:44 AM


Re: Strings and symbols
rocco.rossi@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

Report this thread to moderator Post Follow-up to this message
Old Post
Thomas A. Russ
04-03-08 12:44 AM


Re: Strings and symbols
> >    Constructor Summary 
> From: Frank Buss <f...@frank-buss.de>
> http://java.sun.com/j2se/1.4.2/docs...on.html#JButton(j
avax.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?

Report this thread to moderator Post Follow-up to this message
Old Post
Robert Maas, see http://tinyurl.com/uh3t
04-03-08 03:57 AM


Re: Strings and symbols
> From: rocco.ro...@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.

Report this thread to moderator Post Follow-up to this message
Old Post
Robert Maas, see http://tinyurl.com/uh3t
04-03-08 03:57 AM


Re: Strings and symbols
> From: Alan Crowe <a...@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.

Report this thread to moderator Post Follow-up to this message
Old Post
Robert Maas, see http://tinyurl.com/uh3t
04-03-08 11:28 AM


Sponsored Links




Last Thread Next Thread Next
Pages (3): « 1 2 [3]
Search this forum -> 
Post New Thread

Lisp archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 02:18 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.