Author Topic: mapcar or foreach  (Read 3433 times)

0 Members and 1 Guest are viewing this topic.

curmudgeon

  • Newt
  • Posts: 194
mapcar or foreach
« on: May 25, 2012, 03:41:02 PM »
they both work - I have never made much use of mapcar. but then, I didn't always appreciate the times to use if and when to use a cond statement.

does either one of these have an advantage?

Code: [Select]
(mapcar 'mode_tile '("dr_gr" "dr_ao" "dr_ex" "dr_pd" "jmb_p") '(1 1 1 1 1))
(foreach z '("dr_gr" "dr_ao" "dr_ex" "dr_pd" "jmb_p") (mode_tile z 1))

thanks
Never express yourself more clearly than you are able to think.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: mapcar or foreach
« Reply #1 on: May 25, 2012, 03:45:51 PM »
The second one's intent is far clearer to me, and is less likely to break when adding a new tile key and thus enjoys significant preference over the first.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

curmudgeon

  • Newt
  • Posts: 194
Re: mapcar or foreach
« Reply #2 on: May 25, 2012, 03:57:33 PM »
thank you. I guess I am STILL looking for a place in  my code where mapcar is the best choice.
have to agree with you, and I did not have to state the second list '(1 1 1 1 1) explicitly.

cheers.
getting to enjoy dialog boxes.
 8-)
Never express yourself more clearly than you are able to think.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: mapcar or foreach
« Reply #3 on: May 25, 2012, 04:02:11 PM »
I guess I am STILL looking for a place in  my code where mapcar is the best choice.

When you wish the result of action performed upon a list to be returned as some embellished version of said list. I'm sure others will chime in with examples. Too much on the go; cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: mapcar or foreach
« Reply #4 on: May 25, 2012, 04:41:00 PM »
mapcar may be useful too when you're dealing with more than one list, even you don't want the expression to return a list.

Code - Lisp: [Select]
  1. (mapcar
  2.   '(lambda (f v)
  3.      (eval
  4.        (list
  5.          'defun
  6.          f
  7.          ()
  8.          (list 'command "_.view" v)
  9.          '(princ)
  10.        )
  11.      )
  12.    )
  13.   '(c:0 c:1 c:2 c:3 c:4 c:5 c:6 c:7 c:8 c:9)
  14.   '("_bottom" "_swiso" "_front" "_seiso" "_left" "_top" "_right" "_nwiso" "_back" "_neiso")
  15. )
Speaking English as a French Frog

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: mapcar or foreach
« Reply #5 on: May 25, 2012, 04:52:27 PM »
Salient point and practical example. Thanks Gile.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: mapcar or foreach
« Reply #6 on: May 25, 2012, 05:00:45 PM »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

curmudgeon

  • Newt
  • Posts: 194
Re: mapcar or foreach
« Reply #7 on: May 25, 2012, 08:53:30 PM »
very useful. after reading several versions, it may be sinking in.
need coffee.
thanks again.
Never express yourself more clearly than you are able to think.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: mapcar or foreach
« Reply #8 on: May 26, 2012, 02:07:51 AM »
Gile's version using foreach instead ;) :
Code - Auto/Visual Lisp: [Select]
  1. (foreach item '((c:0 . "_bottom") (c:1 . "_swiso") (c:2 . "_front") (c:3 . "_seiso")...)
  2.   (eval (list 'defun (car item) () (list 'command "_.view" (cdr item)) '(princ))))
IMO mapcar is only to be used when you want to modify the list somehow. It's not that it's "wrong" as such, there's 2 reasons I like foreach better in this case:
  • You don't need a lambda
  • When compiling, foreach optimizes better than mapcar.
Only issue with foreach is it only works on one list. But then you could use mapcar to combine two (or more) lists into one so you can send them to foreach. E.g. modifying the above to use the best parts of mapcar and foreach together:
Code - Auto/Visual Lisp: [Select]
  1.                       '(c:0 c:1 c:2 c:3 c:4 c:5 c:6 c:7 c:8 c:9)
  2.                       '("_bottom" "_swiso" "_front" "_seiso" "_left" "_top" "_right" "_nwiso" "_back" "_neiso"))
  3.   (eval (list 'defun (car item) () (list 'command "_.view" (cdr item)) '(princ))))

Notice the mapcar uses cons to combine the items from both lists into a dotted pair as I had in the previous sample.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.