Dynamic Variables in Lisp Case Statement

I wrote this piece of code in general lisp (ignore ... since it is pointless to insert this part here).

(case turn (*red-player* ...) (*black-player* ...) (otherwise ...)) 

red-player and black-player are variables that were defined using the defvar statement to "mimic" the #define statement in C.

 (defvar *red-player* 'r) (defvar *black-player* 'b) 

As you can imagine, when the variable turn receives either the value *red-player* ('r) or *black-player* value (' b), the case statement does not work properly, as it expects this rotation to contain *red-player* as a literal, not the contents of the variable *red-player* .

I know that I can easily fix this with the cond or if + equal statements, as the contents of the variable are evaluated there, but I'm curious. Perhaps there is a way to create something like C macros in Lisp, or there is some special case statement that allows variables to be used instead of literals.

Thank you in advance!

+4
source share
3 answers

You can abuse Lisp in any way convenient for you. It is as flexible as, unlike C.

It is not always like the use on which you put it. Why push Lisp around?

Try this approach:

  (defvar *turn* nil) (cond ((eq *turn* 'red) ... (setq *turn* 'black))) ((eq *turn* 'black) ... (setq *turn* 'red))) (t .......)) 
+2
source

You can enter the value of expressions in your forms with an estimate of the reading time.

 CL-USER 18 > (defvar *foo* 'a) *FOO* CL-USER 19 > (defvar *bar* 'b) *BAR* CL-USER 20 > '(case some-var (#.*foo* 1) (#.*bar* 2)) (CASE SOME-VAR (A 1) (B 2)) 

Note that reading read time is not always the best idea to improve code maintenance and security.

Note also that the idea that there is a variable with a descriptive name for some internal value is optional in Lisp:

 dashedline = 4 drawLine(4,4,100,100,dashedline) 

will be in lisp

 (draw-line 4 4 100 100 :dashed-line) 

Descriptively named characters can be passed to Lisp. An API type that uses integer values ​​or similar is only needed in the API for external software, usually written in C.

+5
source

Short answer: "Yes, you can do it."

And the seeds of a longer answer suggest using defmacro to create your own version of the case , say mycase , which will return the regular form of the case . The macro you define will evaluate the title of each list in the body enclosure.

You would call:

 (mycase turn (*red* ...) (*black* ...) (otherwise ...)) 

which will return

 (case turn ((r) ...) ((b) ...) (otherwise ...)) 

for the appraiser. The returned case form will then be evaluated the way you want.

Then you can continue to program in your own c-esque style to the horror of whiskey everywhere! Win-win?

+4
source

Source: https://habr.com/ru/post/1332619/


All Articles