I\'m a total Lisp n00b, so please be gentle.
I\'m having trouble wrapping my head around CL\'s idea of an [un-]declared free variable. I would think that:
In lisp variables may be declared usingdefparameter
ordefvar
.
(defparameter var1 5)
(defvar var2 42)
This results in global (dynamic) variables.
The difference between defvar
and defparameter
is that defvar
does not reinitialize an already existing variable.
Local (lexical) variables are introduced e.g using let
or let*
(which initializes the variables sequentially).
Undeclared free variable means that you have used (here setq
-ed) a variable that it is not bound in the context it is used. It may then be declared for you, but then probably as a global (dynamic) variable. The consequence of this is that if you use undeclared variables with the same name in several functions, you will be referencing the same variable in all of the functions.
Your code can be written like this:
(loop for x from 0 to (- (length str) str-len) do
(let* ((last (+ x str-len)) ; get the last char of substring
(subs (subseq str x last)) ; get the substring
(prod (prod-string subs))) ; get the product of that substring
(if (> prod max) ; if it's bigger than current max, save it
(setq max prod)
(setq max-str subs))))
Using the variable-binding properties of loop, it may also be written as
(loop for x from 0 to (- (length str) str-len)
for last = (+ x str-len)
for subs = (subseq str x last)
for prod = (prod-string subs)
when (> prod max) do
(setq max prod)
(setq max-str subs))