newLISP Fan Club

Forum => Anything else we might add? => Topic started by: cormullion on January 25, 2007, 10:05:03 AM

Title: Basic evaluation confusion again, this time with replace
Post by: cormullion on January 25, 2007, 10:05:03 AM
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... ;-)
Title:
Post by: Lutz on January 25, 2007, 10:17:11 AM
(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
Title:
Post by: cormullion on January 26, 2007, 09:28:31 AM
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...!
Title:
Post by: Lutz on January 26, 2007, 11:53:16 AM
'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