foreach capability

foreach capability

john.uhden
Mentor Mentor
402 Views
3 Replies
Message 1 of 4

foreach capability

john.uhden
Mentor
Mentor

You probably already know that (foreach  a b (...)) will operate as though a is each of the members of a list b.

And that a is automatically treated as a local.

But what if a and b are the same symbol?

Let's (setq a '(1 2 3 4))

You may think that you have to treat a not a a symbol, but as the value of a symbol...

Command: (foreach a (eval 'a) (print (setq a (* 2 a)))(princ))

2
4
6
8

But you don't.  foreach treats the first argument as a local and the second argument as an evaluated list.
So as odd as it may look, you can do the following:

Command: (foreach a a (print (setq a (* 2 a)))(princ))

2
4
6
8

Command: !a
(1 2 3 4)

I don't mean to belittle mapcar, just pointing out a cool feature if you're running out of symbol names or your mapcar gets lost on the back roads.

John F. Uhden

403 Views
3 Replies
Replies (3)
Message 2 of 4

john.uhden
Mentor
Mentor

Thanks, John, for teaching me something I didn't know.  🤔

 

John F. Uhden

0 Likes
Message 3 of 4

john.kaulB9QW2
Advocate
Advocate

Playing around so forgive me if I'm off base, but wouldint it be:

(setq a '(1 2 3 4))
(foreach a a (print (* 2 a)) (princ)) ; -i.e. no `setq`.

But, if we step back a bit and look at the "program design phase" we should be going down this sort of path, shouldn't we (to be more descriptive/flexible/etc)?

 

; support function
(defun double (n) (print (* 2 n)))

; usage (either or):
(mapcar 'double a)
(foreach a a (double a))

 

However, on the topic of local variable bindings. Instead of following the typical form (using another example instead of a looping construct):

(defun f (x y / a b)
  (setq a (1+ (* x y))  ; local: a
        b (1- y)        ; local: b
        )
  (+ (* x (* a a))
     (* y b)
     (* a b))
  )

 

We can use lambda to bind the local variables -i.e. use the "let construct":

(defun f (x y)
  (
   (lambda (a b)
     (+ (* x (* a a))
        (* y b)
        (* a b)) )
   (1+ (* x y))         ; local: a
   (1- y))              ; local: b
  )

 

I just did a little write up on the "let/lambda construct" in AutoLisp.

another swamper
0 Likes
Message 4 of 4

john.uhden
Mentor
Mentor

@john.kaulB9QW2 

I'm not getting your point in your last snippet.

Everything is local by definition.  Not much to learn there about foreach capability.

But your interest and participation in this discussion is welcomed.  Your thoughts are valuable.

John F. Uhden

0 Likes