Page 1 of 1

Recursive Version of let?

Posted: Tue Dec 13, 2011 8:07 pm
by ouphe
Hello,

Is there a recursive version of let? For example, I know two variables can be declared this way:

Code: Select all

(let ((a 1)
	   (b 2))
  (+ a b))
...but I would like to do something like this:

Code: Select all

(let ((a 1)
	   (b (+ a 1)))
  (+ a b))
So, is there something similar to let that works recursively, i.e. labels vs. flet?

Thanks.

Re: Recursive Version of let?

Posted: Wed Dec 14, 2011 12:38 am
by smithzv
let* is what you are looking for. But it really isn't exactly analogous to flet and labels. The bindings happen in the order specified.

Re: Recursive Version of let?

Posted: Wed Dec 14, 2011 12:39 am
by ramarren
There is LET*. It is not recursive as such, since recursive means being defined by itself, which, unlike functions, is an extremely rare use case for variables, but it does what you want in your example.

Re: Recursive Version of let?

Posted: Wed Dec 14, 2011 1:01 am
by ouphe
Thanks to Ramarren and smithzv for the pointer to let* and the clarification on recursion. I genuinely appreciate it.

One more thing: assuming my (admittedly amateur) problem should ever occur, which of the two examples would be better coding practice (using let* instead of let in the second, of course)?

Re: Recursive Version of let?

Posted: Wed Dec 14, 2011 8:55 am
by saulgoode
ouphe wrote:One more thing: assuming my (admittedly amateur) problem should ever occur, which of the two examples would be better coding practice (using let* instead of let in the second, of course)?
Well, "better" depends upon what your goals are. Are you aiming for faster execution, fewer memory resources, et cetera?

In my opinion, the "better" coding practice is generally the one that more accurately reflects what is being modeled or, in other words, the form that is most "readable". Of your examples, I am thinking that the latter one is probably "better"; assuming that "(+ a 1)" is in and of itself a meaningful entity.

By way of example, I would submit that the first of the following forms is more understandable to anybody who is reading the code. In fact, if you were to use the second form (for reasons of speed or size optimization) then it would be extremely advisable that you add a comment block describing where "800" comes from and explaining why you wrote the code the way you did.

Code: Select all

(let* ((line-width 80)
       (line 10)
       (char-offset 5) )
  (+ (* line-width line) char-offset) )

(let* ((location 800)
       (char-offset 5) )
  (+ location char-offset) )

Re: Recursive Version of let?

Posted: Wed Dec 14, 2011 9:41 am
by smithzv
An aside, I suppose a "recursive let" (interpreted the same way labels allows for recursive functions) would mean I could do something like:

Code: Select all

(let ((phi (+ 1 (/ phi))))
  phi)
which would bind phi here to the golden ratio. In order to write this macro, you would have to be able to solve arbitrary equations, which we know isn't possible in all cases (we need not go further than noting that some equations are transcendental).