pass symbols to mapcar

pass symbols to mapcar

TanguyNed
Advocate Advocate
905 Views
13 Replies
Message 1 of 14

pass symbols to mapcar

TanguyNed
Advocate
Advocate

Hello,

 

Sorry if that's a dumb question, I'm only a casual developer.

 

This code below returns a syntax error when I try to execute it. I fail to understand why. The problem is with the (apply 'setq x) part.

 

(mapcar '(lambda (x)  (OR (eval (car x)) (apply 'setq x)))
	'((*param1* 1.00)
	  (*param2* "Active")
	  (*param3* 0.02))
)

 

Any help appreciated.

0 Likes
Accepted solutions (1)
906 Views
13 Replies
Replies (13)
Message 2 of 14

_gile
Consultant
Consultant
(mapcar '(lambda (sym val)
	    (or (eval sym) (set sym val))
	  )
	 '(*param1* *param2* *param3*)
	 '(1.00 "Active" 0.02)
 )


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 14

_gile
Consultant
Consultant

Maybe (boundp sym) is more self explanatory than (eval sym)

(mapcar '(lambda (sym val)
	    (or (boundp sym) (set sym val))
	  )
	 '(*param1* *param2* *param3*)
	 '(1.00 "Active" 0.02)
 )

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 14

_gile
Consultant
Consultant
Accepted solution

With a single list of lists as in your first post, you have to use (apply  'set x) instead of (apply 'setq x) because (car x) is already quoted (due to the fact it's an item of a quoted list).

 

(mapcar	'(lambda (x) (or (eval (car x)) (apply 'set x)))
	'((*param1* 1.00)
	  (*param2* "Active")
	  (*param3* 0.02)
	 )
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 14

ronjonp
Mentor
Mentor

A few more:

 

(mapcar	'(lambda (x) (set (car x) (cadr x)))
	'((*param1* 1.00) (*param2* "Active") (*param3* 0.02))
)
(foreach i '((*param1* 1.00) (*param2* "Active") (*param3* 0.02))(set (car i) (cadr i)))
(defun _set (x) (set (car x) (cadr x)))
(mapcar	'_set
	'((*param1* 1.00) (*param2* "Active") (*param3* 0.02))
)

 

And if you don't need to set variables, you could use an association list and pull the values using a key:

 

(cadr (assoc "*param2*" '(("*param1*" 1.00) ("*param2*" "Active") ("*param3*" 0.02))))

 

 

0 Likes
Message 6 of 14

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

A couple more: ....


Those look like they will just set those values into those variables, regardless.  @TanguyNed, am I correct that you want each one set only if there is not already a value in that variable?

Kent Cooper, AIA
0 Likes
Message 7 of 14

TanguyNed
Advocate
Advocate

@Kent1Cooper Yes that is correct.

@_gile I didn't know the existence of the (set) function, that was my only problem.  I didn't know about (boundp) either.

 

Thanks to all for the very quick answers.

0 Likes
Message 8 of 14

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

A couple more: ....


Those look like they will just set those values into those variables, regardless. 


This is correct. Maybe the OP can clarify.

Here's a simple mod ( which can be applied to all ) to the last example that checks for a nil value:

 

(defun _set (x) (and (null (car x)) (set (car x) (cadr x))))
(mapcar '_set '((*param1* 1.00) (*param2* "Active") (*param3* 0.02)))

 

*Edit .. which I guess as a literally quoted list won't work so you'd have to stick with eval.

0 Likes
Message 9 of 14

_gile
Consultant
Consultant

@TanguyNed  a écrit :

@_gile I didn't know the existence of the (set) function, that was my only problem.


(setq a 42) stands for: (set (quote a) 42) or (set 'a 42)



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 10 of 14

TanguyNed
Advocate
Advocate

This does make sense, the "q" means "quote"!  The functions' names are often an abbreviation of something, I've been using them without really understanding what they mean. There are other examples (atof??? or even car/cdr?). Guess that's what happens when you have no formal prior knowledge about coding.

0 Likes
Message 11 of 14

_gile
Consultant
Consultant

atof si quite simple: alphabetic to float.

car and cdr, which are fundamental functions of all LISP languages, are more obscure. They are the acronyms of, respectively, 'contents of the address part of register' and 'contents of the decrement part of register' which are related to the basic structure of LISP lists: the cons cell whose name comes from the cons function, another fundamental function of LISP languages.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 12 of 14

Sea-Haven
Mentor
Mentor

Another method is as you can have as many variables as you want that match the number of items in a list. Its a more global approach for any code where you want common variable names.

 

 

 

(setq lst '(1.00  "Active" 0.02))
(setq num 0)
(mapcar '(lambda (x) (set (read (eval (strcat "*param" (rtos (setq num (1+ num)) 2 0) "*"))) x)) lst)

 

 

 Convert a list to a sequence of variable names (theswamp.org)

0 Likes
Message 13 of 14

martti.halminen
Collaborator
Collaborator

 

The historical origin of car and cdr is as assembly language commands XCARF and XCDRF on an IBM 704.

 

For anybody interested in ancient history, these may be interesting:

 

https://dl.acm.org/doi/pdf/10.1145/800055.802047

https://dl.acm.org/doi/pdf/10.1145/321021.321022

https://en.wikipedia.org/wiki/IBM_704

 

- Though they may be a little heavy reading; the early Lisp literature is not famous for its readability.

0 Likes
Message 14 of 14

TanguyNed
Advocate
Advocate

Thank you all again, my needs are simple but this is all very educational. I will make sure to read the links that were mentioned.

0 Likes