Author Topic: IF / AND help  (Read 466 times)

0 Members and 1 Guest are viewing this topic.

sln8458

  • Newt
  • Posts: 61
  • CMS Intellicad 9.0
IF / AND help
« on: January 05, 2021, 12:32:37 PM »
I'm progressing with my piping dialogue, basically a glorified insertion tool.


I now have all of the Fittings and Flanges happily working, but before I progress with the various valves I decided to add in a 'Pipe' option.
The basic functionality is to set the ucs/draw the 2 circles defining the inside and outside diameters/extrude these circles between 2 user selected points.
Again this is working.

However I am struggling with the IF/AND statements which is used to define the final action when the OK button is selected.
Here is the code:
Code: [Select]
(defun INSERT_BLOCK_VIEW ()
     (if (= NEWTILE "rb31")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb32")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb33")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb34")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb35")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb36")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb37")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb41")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb42")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb43")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb44")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
    (if (= NEWTILE "rb45")
    (SET_BLOCK) ;GOTO SET BLOCK
  ) ;_ end of if
      (if
(and (= NEWTILE "rb46")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
(SET_BLOCK)
) ;_ end of if
;    (if (= NEWTILE "rb46")
;    (SET_BLOCK) ;GOTO SET BLOCK
;  ) ;_ end of if
    (if
(and
(= NEWTILE "rb47")
(= sel "pipe_")
) ;end and
(DRAW_PIPE_SHAPE)
(SET_BLOCK)
) ;_ end of if
;    (if (= NEWTILE "rb47")
;    (SET_BLOCK) ;GOTO SET BLOCK
;  ) ;_ end of if
  (if
(and
(= NEWTILE "rb48")
(= sel "pipe_")
) ;end and
(DRAW_PIPE_SHAPE)
(SET_BLOCK)
) ;_ end of if
;    (if (= NEWTILE "rb48")
;    (SET_BLOCK) ;GOTO SET BLOCK
;  ) ;_ end of if
(if
(and
(= NEWTILE "rb49")
(= sel "pipe_")
) ;end and
(DRAW_PIPE_SHAPE)
(SET_BLOCK)
) ;_ end of if
 ) ;end INSERT_BLOCK_VIEW
 (defun SET_BLOCK ()
  (setq D  (nth 1 SIZE_DIMS)
  ) ;end setq
  (INSERT_BLOCK) ;GOTO INSERT BLOCK
 ) ;End SET_BLOCK
  ;-----------------------------------------------------------------------;
(defun INSERT_BLOCK ()
  ;(princ D) ; print the content of D variable to the command line.
  (if (tblsearch "block" D)
    (progn
     (command "_.-insert" D pause "" "" ""))
(progn
      (setq dwg (strcat D ".dwg"))
      (if (setq fullPath (findfile dwg))
(command "_.-insert" fullPath  pause "" "" "")
(Princ (strcat "\nNot found drawing name <" dwg "> in support file search path.")) )) )
  (princ))
  ;-----------------------------------------------------------------------;
  ;for ICAD 9.0 ONLY

(defun DRAW_PIPE_SHAPE ( / spt1 spt2 ENT1 ENT2 PIPOD PIPID)
(setq PIPOD N1)
(setq PIPID N6)
 (if (and (setq spt1 (getpoint "\nSpecify Start point of Pipe"))
          (setq spt2 (getpoint "\nSpecify End point of Pipe"))
     ) ;end of AND
   (progn
(command "ucs" "ZA" spt1 spt2)
(command "circle" "0,0,0" "d" pipod) ;take OD from dim file
(setq ENT1 (entlast))
(command "circle" "0,0,0" "d" pipid) ;take ID from dim file
(setq ENT2 (entlast))
    (command "extrude" ENT1 "" "D" spt1 spt2)
(setq ENT1 (entlast))
    (command "extrude" ENT2 "" "D" spt1 spt2)
(setq ENT2 (entlast))
    (command "subtract" ENT1 "" ENT2 "")
(command "ucs" "_P")
    ) ;_ end of progn
   )  ;_ end of IF  
) ;end DRAW_PIPE_SHAPE

  ;for ICAD 9.0 ONLY

The problem:
I first added the if/and to rb49 and it worked as I was expecting/hoping. However when I added it to rb46-rb48 I ran into the problem.
When inserting a fitting or flange I get multiple requests for 'insertion point'. I have established that I get 1 insertion point for each IF/AND statement, as each time I added the if/and I got another insertion point, 2 then 3 then 4.
So the code above gives 4 insertion points before the insert command ends.

Can anyone see where I'm going wrong?

Steve.
There is no such  thing as a 'silly question' to those who do not know!

Grrr1337

  • Swamp Rat
  • Posts: 748
Re: IF / AND help
« Reply #1 on: January 05, 2021, 06:54:37 PM »
Can anyone see where I'm going wrong?

Hi, Lets clear some things up -

The if function in LISP wraps up both, the then and else evaluation blocks:
Code - Auto/Visual Lisp: [Select]
  1. (if (condition)
  2.   (evaluate_if_true)
  3.   (evaluate_if_false) ; this is optional
  4. ); if

In languages like C# it would look like this:
Code - C#: [Select]
  1. if (condition)
  2. {
  3.   // evaluate_if_true
  4. }
  5. else // this is optional block
  6. {
  7.   // evaluate_if_false
  8. }

But in there you can also include multiple else if blocks
(which is different in terms of evaluation, than copying multiple single if-else statements) :

Code - C#: [Select]
  1. if (condition1)
  2. {
  3.   // evaluate_for_condition1
  4. }
  5. else if (condition2) // this is optional block, aswell the below ones
  6. {
  7.   // evaluate_for_condition2
  8. }
  9. else if (condition3)
  10. {
  11.   // evaluate_for_condition3
  12. }
  13. else
  14. {
  15.   // evaluate_if_no_condtion_is_matched
  16. }

The above C# syntax example will check for the first condition that matches and won't bother checking the rest.

Problem is when you copy single if-else statements multiple times (just like you did),
the evaluation inside the function doesn't stop at the first matching condition, but rather
continues checking for the rest conditions and seek to evaluate whatever if matches true.

Unfortunately in LISP there are no multiple 'else if' built-in function, but theres cond -
which works similarly to the 2nd C# syntax I've mentioned - the one with multiple else if blocks.

Code - Auto/Visual Lisp: [Select]
  1.   ( (condition1) ; this is an 'if' block
  2.     ; evaluate_for_condition1
  3.   )
  4.   ( (condition2) ; this is an 'else if' block [optional]
  5.     ; evaluate_for_condition2
  6.   )
  7.   ( (condition3) ; this is an 'else if' block [optional]
  8.     ; evaluate_for_condition3
  9.   )
  10.   (t ; this is an 'else' block [optional]
  11.     ; evaluate_if_no_condtion_is_matched
  12.   )
  13. ); cond

I'm sure that after reading the above you still won't understand what I said (nothing personal), so I'll provide an comparsion example
for you to observe whats the difference between evaluating multiple copied if statements and multiple else-if statements (cond)
used for overlapping conditions -

Code - Auto/Visual Lisp: [Select]
  1. (defun Multiple_If_Statements ( / x )
  2.  
  3.   (setq x 5)
  4.  
  5.   (if (numberp x)
  6.     (alert "if_Block1: Yes, x is a number.")
  7.     ; (alert "if_Block1: No, x is not a number.")
  8.   )
  9.   (if (and (numberp x) (<= x 5))
  10.     (alert "if_Block2: Yes, x is a number, and is below or equal to five.")
  11.     ; (alert "if_Block2: No, x is not a number or its not below or equal to five.")
  12.   )
  13.   (if (and (numberp x) (>= x 0))
  14.     (alert "if_Block3: Yes, x is a number, and is above or equal to zero.")
  15.     ; (alert "if_Block3: No, x is not a number or its not above or equal to zero")
  16.   )
  17. )
  18. (Multiple_If_Statements)

Code - Auto/Visual Lisp: [Select]
  1. (defun Multiple_Else_If_Statements ( / x )
  2.  
  3.   (setq x 5)
  4.  
  5.   (cond
  6.     ( (numberp x)
  7.       (alert "if_Block1: Yes, x is a number.")
  8.     )
  9.     ( (and (numberp x) (<= x 5))
  10.       (alert "else_if_Block2: Yes, x is a number, and is below or equal to five.")
  11.     )
  12.     ( (and (numberp x) (>= x 0))
  13.       (alert "else_if_Block3: Yes, x is a number, and is above or equal to zero.")
  14.     )
  15.   ); cond
  16. ); defun
  17. (Multiple_Else_If_Statements)

When you run the first function (Multiple_If_Statements) you should get the 3 alert messages,
and when you run the second function (Multiple_Else_If_Statements) you should get only 1 alert message.
Maybe you still won't get whats the big deal about this, but imagine that
every condition in both examples were substituted with yours:
Code: [Select]
(= NEWTILE "rb48")and also:
Code: [Select]
(and
  (= NEWTILE "rb48")
  (= sel "pipe_")
) ;end and

and each alert message was substituted with yours:
Code: [Select]
(DRAW_PIPE_SHAPE)
(SET_BLOCK)

meaning that if you prompt for a point inside the call-function, your checking-function would x3 times that prompt.
So that makes two completely different programs.  :roll:

Understanding how conditionals work is essential for any programming language,
so I suggest for you to play/experiment with small parts of your program, some obvious conditionals, along with alert or print functions
In order to understand how it works and whats the logic behind it.


ASIDE TALK:
BTW theres a related, common programming question about on how to stop the evaluation after the first matching occurence of an iterative datastructure in a 'x' language.
So far in my exploration I've collected these:
Code: [Select]
LISP:
(vl-some '(lambda) (list))

C#:
<Array class>.FirstOrDefault()
<List class>.Any()

JavaScript:
<array>.some()

Not to mention the commonly known -
Code: [Select]
for(i = 0; i < arr.length ; i++)
{
  if (condition_for arr[i])
  {
    // do stuff...
    break;
  }
}
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9553
Re: IF / AND help
« Reply #2 on: January 05, 2021, 09:17:11 PM »
Use COND instead of those ugly IF statements; COND is your primary conditional statement in AutoLisp and I believe (hard to remember my AutoLisp) it also stops evaluating once a non-nil condition is met so it's often "cleaner".

On the nesting of if-else note: I, personally, avoid if-else nesting. If I have to use more then one else, I try to break the code up into sub-routines or simpler logic. This tends to create less error-prone code. 

Here is an example:
I was just writing some C code to open a file (doing some "error handling and proper method stuff" and the logic for the open portion was getting a little too complicated, so I broke out the code into a sub.

Here is my sub-routine:
Code - C++: [Select]
  1. /*------------------------------------------------------*- C -*------
  2.  * r_open
  3.  *  An `open` which restarts `open` after a signal occurs.
  4.  *
  5.  * ARGS
  6.  *  const char *path    :   A path
  7.  *  int oflag           :   Open flag(s)
  8.  *
  9.  * RETURN
  10.  *  int                 :   File descriptor
  11.  *
  12.  *-------------------------------------------------------------------*/
  13. int r_open(const char *path, int oflag) {
  14.   int myfd;
  15.   while ((myfd = open(path, oflag)) == -1 &&
  16.       errno == EINTR)
  17.     ;
  18.   if (myfd == -1) {          // it was a real error, not a signal
  19.     perror("failed to open the file");
  20.    }
  21.   return myfd;
  22. }

This resulted in very clean code instead of nasty if-else statements in my main function:
Code - C++: [Select]
  1.   if ((fromfd = r_open(argv[1], READ_FLAGS)) == -1) {
  2.     perror("Failed to open input file");
  3.     return 1;
  4.   }

A little background into why my initial error-handling-logic was getting a little complicated (if you actually care):
In C, the open function returns 1 if the file doesn't exist, the open call was interrupted by a signal or the process doesn't have the appropriate access permissions. If your code uses the file descriptor for a subsequent read or write operation, the operation fails.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

sln8458

  • Newt
  • Posts: 61
  • CMS Intellicad 9.0
Re: IF / AND help
« Reply #3 on: January 06, 2021, 04:31:13 AM »
Hi Grrr1337/John,

Thank you both for the detailed replies, it will take me a few re-reads to take it all in (it's an age thing  :whistling:)

After a little 'playing' this is what I have, and it works  :-D
Code: [Select]
(cond
((and (= NEWTILE "rb41")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb42")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb43")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb44")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb45")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb46")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb47")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb48")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE)
)
;
((and (= NEWTILE "rb49")(= sel "pipe_")) ;end and
(DRAW_PIPE_SHAPE) ;goto draw pipe shape
)
(t (SET_BLOCK))  ;goto set block
) ;_ end of cond
;
; (cond
; ((<IF this is true>)
;   (<THEN do this>)
;   )
;   (t (<ELSE do this>)
;   )
;
;
 ) ;end INSERT_BLOCK_VIEW

Please forgive the extra spacing's, this was just for me to help me see whats going on.

Thanks again for the help.
.
There is no such  thing as a 'silly question' to those who do not know!

Tharwat

  • Swamp Rat
  • Posts: 570
  • Hypersensitive
Re: IF / AND help
« Reply #4 on: January 06, 2021, 05:09:58 AM »
Hi,
Based on your last posted codes with cond function, so here is another way.
Code - Auto/Visual Lisp: [Select]
  1. (if (and (wcmatch NEWTILE "rb41,rb42,rb43,rb44,rb45,rb46,rb47,rb48,rb49")
  2.          ;; or you can use memmber or vl-position functions instead of wcmatch function if you want to as commented below.
  3.          ;; (member NEWTILE '("rb41" "rb42" "rb43" "rb44" "rb45" "rb46" "rb47" "rb48" "rb49"))
  4.          (= sel "pipe_")
  5.     )
  6.   (DRAW_PIPE_SHAPE)
  7.   (SET_BLOCK)
  8. )
  9.  

roy_043

  • Water Moccasin
  • Posts: 1845
  • BricsCAD 18
Re: IF / AND help
« Reply #5 on: January 06, 2021, 09:23:02 AM »
it also stops evaluating once a non-nil condition is met so it's often "cleaner".
Huh, are you saying that this does not apply to the if function?

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9553
Re: IF / AND help
« Reply #6 on: January 06, 2021, 09:30:56 AM »
Looks better, sln8458. You are getting the logic but I'm not sure you need the "AND ...NEWTILE...= sel "pipe_" for each condition.

Fortunately, Tharwat has been kind enough to give you the next method to use in these types of problems. He is using a lookup table to match against. It's important to understand, his "(wcmatch NEWTILE "rb41,rb42,rb43..." statement is essentially preforming the same operation as your COND -i.e. checking each case against a known value. However, I do not believe wcmatch or member will stop its operation upon success and it will just continue checking each remaining item in the list (this gets into the aside discussion Grrr1337 brought up about breaking once a value has been found).
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9553
Re: IF / AND help
« Reply #7 on: January 06, 2021, 09:41:27 AM »
it also stops evaluating once a non-nil condition is met so it's often "cleaner".
Huh, are you saying that this does not apply to the if function?

Not sure I understand your question...

A series of IF statements will be run (each).
IF <test>
IF <test>
IF <test>

The only way to stop evaluating (warning: this is fuzzy memory) is to wrap the IFs in a boole.
(AND (IF <test> ... (IF <test> ...
But then you return a T/F value not the last subsequent value returned.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

sln8458

  • Newt
  • Posts: 61
  • CMS Intellicad 9.0
Re: IF / AND help
« Reply #8 on: January 06, 2021, 12:27:20 PM »
Oh, what have I done  :opps:, those last comments were so far above my head I only heard them pass over!! :uglystupid2: :2funny:
More reading I think.
There is no such  thing as a 'silly question' to those who do not know!

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9553
Re: IF / AND help
« Reply #9 on: January 06, 2021, 01:59:10 PM »
Oh, what have I done  :opps:, those last comments were so far above my head I only heard them pass over!! :uglystupid2: :2funny:
More reading I think.
No! You made a good leap; you have the basics now. The comments so far have been about mythology (programming). Stick with what you understand, do not worry about optimization yet (use what works; there is more then enough expertise here to help optimize methods once you grasp concepts).

Recap of the thread:
You will have this same scenario constantly and you have a few methods you can use. You can combat this with a couple of methods. One being a conditional evaluation (check, check, check--do!) or a look-up table (which is similar). Each have their ups-and-downs.

For example, you can do the check, check, check--do (where the checking stops after the first pass) or the look up table method and risk running checks for items past the first passed check.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

roy_043

  • Water Moccasin
  • Posts: 1845
  • BricsCAD 18
Re: IF / AND help
« Reply #10 on: January 06, 2021, 05:25:21 PM »
A series of IF statements will be run (each).
Of course the same goes for a series of cond statements... From what you are saying here inexperienced users may get the idea that there is something wrong with the if function.

BIGAL

  • Swamp Rat
  • Posts: 581
  • 30 + years of using Autocad
Re: IF / AND help
« Reply #11 on: January 06, 2021, 07:38:37 PM »
You can do a not found condition check also handy to trap incorrect input.

Code: [Select]
(cond
((= ans 1)(princ ans))
((= ans 2)(princ ans))
((Alert "The value entered is to large\nwill exit now")(exit))
)
A man who never made a mistake never made anything

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9553
Re: IF / AND help
« Reply #12 on: January 06, 2021, 08:10:49 PM »
A series of IF statements will be run (each).
Of course the same goes for a series of cond statements... From what you are saying here inexperienced users may get the idea that there is something wrong with the if function.

Are we assuming all test cases are false and then running a COND or a series of IF statements will result in all test cases being run? If so, well that is obvious and there isn't anything anyone can do about that.

I was operating under the assumption that test case #2 of 5 (for example) would be true; COND will stop evaluating after #2 tests true and return the result of the operation (test 3-5 will not be run). However if you had 5 IF statements all 5 would run no matter (in our example 3-5 would still run). That is how I interpreted Grrr1337's aside talk about BREAK.

I wasn't saying that anything is wrong with IF, at all (I like IF). Although, I was saying that in the case of several test cases like this, COND should be the primary goto function instead of a series of IFs; but that isn't profound but any stretch.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

sln8458

  • Newt
  • Posts: 61
  • CMS Intellicad 9.0
Re: IF / AND help
« Reply #13 on: January 07, 2021, 03:06:16 AM »
Oh, what have I done  :opps:, those last comments were so far above my head I only heard them pass over!! :uglystupid2: :2funny:
More reading I think.
No! You made a good leap; you have the basics now. The comments so far have been about mythology (programming). Stick with what you understand, do not worry about optimization yet (use what works; there is more then enough expertise here to help optimize methods once you grasp concepts).

Recap of the thread:
You will have this same scenario constantly and you have a few methods you can use. You can combat this with a couple of methods. One being a conditional evaluation (check, check, check--do!) or a look-up table (which is similar). Each have their ups-and-downs.

For example, you can do the check, check, check--do (where the checking stops after the first pass) or the look up table method and risk running checks for items past the first passed check.

Hi John.
I will be sticking with the 'cond' statement that is working for me.
Grrr1337's suggestions does look more 'compact' but for me, a novice (what comes before a novice??) I find it difficult to see what is happening.

As an aside, you guys have been soo helpful. Thanks
There is no such  thing as a 'silly question' to those who do not know!

Grrr1337

  • Swamp Rat
  • Posts: 748
Re: IF / AND help
« Reply #14 on: January 07, 2021, 10:56:37 AM »
Stick with what you understand, do not worry about optimization yet

I double that.
Personally in the threads where I'm the novice one I do include comments in my code (in that certain code block), that will contain a link and the optimised suggestions.
For example:
Code - Auto/Visual Lisp: [Select]
  1. ; http://www.theswamp.org/index.php?topic=56494.0
  2. ;|
  3. (if (and (wcmatch NEWTILE "rb41,rb42,rb43,rb44,rb45,rb46,rb47,rb48,rb49")
  4.          ;; or you can use memmber or vl-position functions instead of wcmatch function if you want to as commented below.
  5.          ;; (member NEWTILE '("rb41" "rb42" "rb43" "rb44" "rb45" "rb46" "rb47" "rb48" "rb49"))
  6.          (= sel "pipe_")
  7.     )
  8.   (DRAW_PIPE_SHAPE)
  9.   (SET_BLOCK)
  10. )
  11. |;
  12.  
  13. (cond ; << copied what sln8458 came up with
  14.         ((and (= NEWTILE "rb41")(= sel "pipe_")) ;end and
  15.         (DRAW_PIPE_SHAPE)
  16.         )
  17. ;
  18.         ((and (= NEWTILE "rb42")(= sel "pipe_")) ;end and
  19.         (DRAW_PIPE_SHAPE)
  20.         )
  21. ;
  22.         ((and (= NEWTILE "rb43")(= sel "pipe_")) ;end and
  23.         (DRAW_PIPE_SHAPE)
  24.         )
  25. ;
  26.         ((and (= NEWTILE "rb44")(= sel "pipe_")) ;end and
  27.         (DRAW_PIPE_SHAPE)
  28.         )
  29. ;
  30.         ((and (= NEWTILE "rb45")(= sel "pipe_")) ;end and
  31.         (DRAW_PIPE_SHAPE)
  32.         )
  33. ;
  34.         ((and (= NEWTILE "rb46")(= sel "pipe_")) ;end and
  35.         (DRAW_PIPE_SHAPE)
  36.         )
  37. ;
  38.         ((and (= NEWTILE "rb47")(= sel "pipe_")) ;end and
  39.         (DRAW_PIPE_SHAPE)
  40.         )
  41. ;
  42.         ((and (= NEWTILE "rb48")(= sel "pipe_")) ;end and
  43.         (DRAW_PIPE_SHAPE)
  44.         )
  45. ;
  46.         ((and (= NEWTILE "rb49")(= sel "pipe_")) ;end and
  47.         (DRAW_PIPE_SHAPE)                                                ;goto draw pipe shape
  48.         )
  49.         (t (SET_BLOCK))                                                  ;goto set block
  50.         ) ;_ end of cond
  51. ;
  52. ;       (cond
  53. ;       ((<IF this is true>)
  54. ;   (<THEN do this>)
  55. ;   )
  56. ;   (t (<ELSE do this>)
  57. ;   )
  58. ;
  59. ;
  60.  ) ;end INSERT_BLOCK_VIEW
  61.  

Then, after a period of time where I happen to understand more and get back to revise my code I am able to see that 'the thing' was discussed already,
and facepalm myself for not understanding it back then in order to optimise it more. But I'm able to track progress this way.

I think its depending on a one's level - balance between optimisation and understanding.
Where by optimisation I mean "short code where one doesn't understand whats happening",
and by understanding "relatively stupid/repetitive code, but understood".


Grrr1337's suggestions does look more 'compact' but for me, a novice (what comes before a novice??) I find it difficult to see what is happening.

Don't worry, its a lifelong thing when one deals with programming.  :cry2:
(I still remember the time where I was writting kilobytes of repetitive code, without the right to claim that I'm writing a "large program")

As an aside, you guys have been soo helpful. Thanks

You're wellcome, cheers!
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)