Вопрос

Is it considered idiomatic or non-idiomatic to have a LET block nested inside aFLET/LABELS block ?

Again, I may be coming at this all wrong, but I'm trying to mimic the generic where block in Haskell (so I have a defun and I want to write code that uses certain temporary bindings for values and functions.

In case these are non-idiomatic (after all, I shouldn't expect to transfer over usage from one language to another), what's the right way to do this ?

E.g. something like (stupid example follows ...)

(defun f (x) (
  (let* ((x 4)
         (y (1+ x))
         (flet ((g (x) (+ 2 x)))
            (g y))))
Это было полезно?

Решение

You want to know if it's a difference of preference between:

(defun f (x)
  (let* ((x 4) (y (1+ x)))
    (flet ((g (x) (+ 2 x)))         
       (g y))))

and

(defun f (x)
  (flet ((g (x) (+ 2 x)))         
    (let* ((x 4) (y (1+ x)))
       (g y))))

?

It really doesn't matter which order you put flet/labels and let/let* in this case. It will produce the same result and your CL implementation might optimize your code such that the result would be the same anyway.

In a LISP-1 you would have put it in the same let and then the question would be if you should put the lambda first or last. Seems like taste to me.

The only case where there is a difference is when you are making calculations that are free variables in your function. Like this:

(defun f (x)
  (let ((y (1+ x)))
    (flet ((g (x) (+ 2 x y))) ; y is free, made in the let*        
       (g x))))

(f 5) ; ==> 13

Switching order is now impossible without moving logic since the function uses a free variable. You could put the let inside the definition of g like this:

(defun f (x)
  (flet ((g (z) ; renamed to not shadow original x
           (let* ((y (1+ x)))
             (+ 2 z y)))         
    (g x))))

But imagine you used it with mapcar, reduce or recursion. Then it would have done the calculation for every iteration instead of once before the call. These are the cases that really matter.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top