Author Topic: LISP Logic and More  (Read 1470 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
LISP Logic and More
« on: November 18, 2006, 03:12:06 PM »
Here is my take on the subject of LISP Logic functions & there usage.

Explore with me the if and or cond while & progn functions.

The if statement works like this
Code: [Select]
(if (this is true)
  (then do this)
)

Code: [Select]
(if (this is true)
  (then do this)
  (else do this when false)
)



The (cond) stmt on the other hand executes the all of code following
a true condition and then exits the condition stmt.

Code: [Select]
(cond
  ((= 1 0)
    none of this will get executed
    because the conditions is false
  ) ; end cond 1

  ((= 1 1)
     do all of this because it is true
     and this
     and this
   ) ; end cond 2

   ((= 2 2)
     none of this will get
     executed even if it is true
     because the prior stmt was true
   ) ; end cond 3

   (T
     This is often placed at the last position
     in a condition statement and will be executed
     if all the prior conditions are false
     if any one of the above conditions are true
      this will not be executed
   ) ; end cond 4
) ; end cond stmt
More on the condition statement in a minute.


The  OR will process each line as long as they are false, it will quit when true is returned
Code: [Select]
(or (a. is true) ; stop here
     (b. does not get this far)
)

Code: [Select]
(or (a. is false) ; keep going
     (b. do this & if false keep going)
     (c. do this if b was false)
)

The  AND will process each line as long as they are true, it will quit when false is returned
Code: [Select]
(and (a. is true) ; keep going
      (b. do this & if true keep going)
      (c. do this if b was true)
)

Note that AND & OR themselves only return true or nil,
whereas IF and COND will return the value of the  expression.
Code: [Select]
(setq rtn
       (or (+ 3 7) ; returns 10 which is not nil so it passes the test for true
            (+ 2 4 6) ; return 12
       )
)
While the value in rtn is t
Code: [Select]
(setq rtn
       (if (+ 3 7) ; returns 10 which is not nil so it passes the test for true
            (+ 2 4 6) ; return 12
       )
)
The value in rtn is 12
Code: [Select]
(setq rtn
       (if (> 3 7) ; 3 is not > 7 so this returns nil
            (+ 2 4 6) ; return 12
       )
)
The value in rtn is nil because there was no else line to consider
Code: [Select]
(setq rtn
       (if (> 3 7) ; 3 is not > 7 so this returns nil
            (+ 2 4 6)
            (- 10 2)
       )
)
No supprise here, the rtn value is 8

The cond statement works simular to the if
Here is an example I like
Code: [Select]
(initget 0 "Yes No")
(setq ans
          (cond
          ((getkword "\nGive your answer.  [Yes/No] <Yes>: "))
                ("Yes")
          )
)
If the user hits the enter key nil is returned and the cond returns "Yes"
If the user enters text the text is returned




Some examples of  (progn
Note that progn returns the value of the LAST evaluated expression.
Code: [Select]
(if (this is true)
   (progn
        do all of this
        and this
        and this
    )
   (don't do this)
); endif

(if (this is false)
   (don't do this)
   (progn
        do all of this
        and this
        and this
    )
)

So you see the progn is a way to group code together.
The (if) stmt will execute the group of code when true and
will execute the second group of code when false,
if there is a second group of code. If you forget the (progn) only the first
line of code will be executed if true and the rest skipped.
There are other ways to group code together and you will learn them in time.




The (cond) stmt on the other hand executes all of the code following
a true condition and then exits the condition stmt. Remember true is anything not nil.

Code: [Select]
(cond
  ((= 1 0)
    none of this will get executed
    because the conditions is false
  ) ; end cond 1

  ((= 1 1)
     do all of this because it is true
     and this
     and this
   ) ; end cond 2

   ((= 2 2)
     none of this will get
     executed even if it is true
     because the prior stmt was true
   ) ; end cond 3

   (T
     This is often placed at the last position
     in a condition statement and will be executed
     if all the prior conditions are false
     if any one of the above conditions are true
      this will not be executed
   ) ; end cond 4
) ; end cond stmt



Here is a trick for the cond statement when you want to conditionally execute the cond.
Often we see it like this:
Code: [Select]
(if (something is true) ; reminder, 'true' here is really anything (not nil)
  (cond
    ((= 1 1) ...)
    ((= 2 2) ...)
  ) ; end cond stmt
) ; endif

It can be written like this so that if something is not true the first condition is true &
nothing is done but the cond statement is satisfied that it found a true condition.
The processing skips the remaining conditions.
Code: [Select]
(cond
  ((not (something is true))) ; if something is not true stop here
  ((= 1 1) ...)
  ((= 2 2) ...)
) ; end cond stmt



The WHILE function as a conditional loop and continues the loop until the next
expression returns nil. Here we test the value in cnt looking for it to become 0
so that we can exit the while loop. The code within the loop is executed 5 times,
while the cnt value is 0 through 4.
Code: [Select]
(setq cnt 0)
(while (= cnt 5)
  ;;  do some stuff
  (setq cnt (1+ cnt))
)

It can also be written like this and the cnt value is 0 through 4.
Code: [Select]
(setq cnt -1)
(while (= (setq cnt (1+ cnt)) 5)
  ;;  do some stuff
)

Sometimes the condition you want to test is set at the end of the code within
the loop. The code may look like this.
Code: [Select]
(setq continue_loop t)
(while continue_loop
  ;;  do some stuff
  (if (I want to leave the loop is true)
    (setq continue_loop nil) ; flag to exit the loop
  )
)

This can also be written like this:
Code: [Select]
(setq continue_loop t)
(while
  (progn
  ;;  do some stuff
   (not (I want to leave the loop is true)) ; flag to exit the loop
  ) ; progn
)

So you see that when  (I want to leave the loop is true) returns true, the not will
return nil and because it is the last expression in the progn, that is the value the
while sees. It then exits the loop.


Here is a real world example.
This is my solution for entering numbers like key words
The simulated key words would be "90 180 270 -90"
Code: [Select]
(while
  (progn
    (setq rang
           (cond ((getint "\nEnter the rotation angle [90/180/270] <90>"))
                 (90)))
    (if (not (vl-position rang '(90 180 270 -90)))
      (not (prompt "\nError  Angle must be 90 180 270, please re-enter.")))
  )
)


That's all for now.
 See ya.

« Last Edit: November 18, 2006, 04:23:31 PM by CAB »
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.