Basic evaluation confusion again, this time with replace

Started by cormullion, January 25, 2007, 10:05:03 AM

Previous topic - Next topic

cormullion

I don't quite understand why this happens. Basically, it's whether a symbol that contains a string evaluates to a string or not when used in replace:


(set 's "string")

(println
(replace s "this is a string"  "rope")  ; symbol OK
)

;-> this is a rope

(set 'l '(
 ("string1" 1)
 (s 2)))

(println
(map (fn (f) (replace (first f) "this is a string"  "rope")) l) ; symbol not OK
)

string expected


You see, I thought that (first f) would give replace either "string1" or s, which is a string (and which is OK). But no.



I get confused like this occasionally... ;-)

Lutz

#1
(replace s "this is a string"  "rope")

here 'replace' evaluates the parameter 's' first to extract the string. But in:


(map (fn (f) (replace (first f) "this is a string"  "rope")) l)

'replace' evaluates '(first f)' and gets either "string1" or the raw un-evaluated symbol 's'.



Lutz

cormullion

#2
Yes, OK. I see more clearly now.



But ...



:-)





if replace is expecting a symbol, and sees an unevaluated symbol instead, why doesn't it , well, evaluate it ...?



Don't worry, I'm sure there's a better reason for the way it does what it does...!

Lutz

#3
'replace' will except anything as the first parameter and then look it up in the list or string following.



As a rule all functions will evaluate their parameters. Only this way it is possible to pass parameters in variables:


(replace key list-or-string)

In this case the variable symbol 'key' has to be evaluated to find out whats inside, which could be a number, string list-expression or anything else to be looked up inside whats in the second varable  'list-or-string'.



For 'key' this could be a symbol itself:


(set 'key 'x)

(replace key '(a b x d e f) 'c) => (a b c d e f)


There are functions which deviate from the rule to evaluate all parameters and these are called special forms. For example in newLISP flow contructs like 'case', 'dotimes', 'dolist' and 'for' are all special forms, in:


(dotimes (i N) exp1 epx2 ...)

the function 'dotimes' has at least two parameters: '(i N)' and one or more expressions 'exp'. The first '(i N)' is not evaluates, but instead the 'dotimes' function looks inside and evalautes 'N' to find out how often to iterate over the exp1,exp2 .... and evaluate them over and over again, N times.



Another examples is 'setq', which does evaluate only its second parameter, but not the first:


(set 'x 'y)

(setq y 123)
(set 'y 123)
(set x 123)

x => y
Y => 123


The 'setq' and 2 following 'set'  statements do all the same, setting the contents of the symbol 'y' to 123. 'setq' is a special form with special evaluation rules, 'set' is not.



Lutz