Tutorial :Consecutive calls/evaluations in a form?



Question:

Hey guys, simple question...

Working with XLISP to write a program, but I've seemed to run into a simple fundamental problem that I can't seem to work around: perhaps someone has a quick fix.

I'm trying to write an if statement who's then-clause evaluates multiple forms and returns the value of the last.

In example:

(setq POSITION 'DINING-ROOM)    (defun LOOK (DIRECTION ROOM) ... )  (defun SETPOS (ROOM) ... )  (defun WHERE () ... )    (defun MOVE (DIRECTION)  (if (not(equal nil (LOOK DIRECTION POSITION))) ; If there is a room in that direction  ( ; Then-block: Go to that room. Return where you are.  (SETPOS (LOOK DIRECTION ROOM))  (WHERE)  )  ( ; Else-block: Return error  (list 'CANT 'GO 'THERE)  )  )  

The logical equivalent intended is:

function Move (Direction)  {    if(Look(Direction, Room) != null)  {  SetPos(Look(Direction,Room));  return Where();  }  else  {  return "Can't go there";  }    }  

(Apologies for the poor web-formatting.)

The problem I have is with:

(  (SETPOS (LOOK DIRECTION ROOM))  (WHERE)  )  

I simply want to return the evaluation of WHERE, but I need to execute the SETPOS function first. XLISP doesn't like the extra parentheses: if I remove the outer set, my WHERE list becomes my else (I don't want that). If I remove the sets around SETPOS and WHERE, it treats WHERE like an argument for SETPOS; I also don't want that.

So, how do I simply evaluate the first, then the second and then return the values of the last evaluated?


Solution:1

Lisp usually provides something like PROGN. PROGN evaluates a sequence of expressions and the value(s) of the last expression is returned.

(progn    (do-this)    (do-that))  

Also look at your code:

(if (not(equal nil (LOOK DIRECTION POSITION)))    (EQUAL NIL (FOO))  is the same as  (NULL FOO)    (NOT (NULL FOO)) is the same as FOO.  

So you can simply write:

(if (LOOK DIRECTION POSITION) ... ...)  

Or if you want to check if there is a room:

(if (ROOM-P (LOOK DIRECTION POSITION)) ... ...)  

ROOM-P would be a predicate that returns T if something is a room.

You may also want to use typical Lisp indentation:

(defun MOVE (DIRECTION)    (if (LOOK DIRECTION POSITION)      (progn        (SETPOS (LOOK DIRECTION ROOM))        (WHERE))      (progn        ...        (list 'CANT 'GO 'THERE))))  

There is also a COND construct:

(defun MOVE (DIRECTION)    (cond ((LOOK DIRECTION POSITION)           (SETPOS (LOOK DIRECTION ROOM))           (WHERE))          (t           ...           (list 'CANT 'GO 'THERE))))  

I would also propose to switch from XLISP to something like CLISP or ECL. XLISP is old, mostly not maintained and not Common Lisp.


Solution:2

So I found a way of doing consecutive executions (whether its the best means or not):

Changed:

(  (SETPOS (LOOK DIRECTION ROOM))  (WHERE)  )  

To:

(let ()  (SETPOS (LOOK DIRECTION ROOM))  (WHERE)  )  

Which executed both forms and returned the output of the last.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »