Author Topic: Abort and return to command prompt  (Read 6071 times)

0 Members and 1 Guest are viewing this topic.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Abort and return to command prompt
« on: August 08, 2012, 05:05:30 PM »
In C# you can use Return to cancel out and return to command prompt, how do you do this in LISP?
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #1 on: August 08, 2012, 05:10:51 PM »
Nevermind, I found it
(exit)
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Abort and return to command prompt
« Reply #2 on: August 08, 2012, 08:17:01 PM »
I find it a rare occasion that I need EXIT?
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.

danallen

  • Guest
Re: Abort and return to command prompt
« Reply #3 on: August 08, 2012, 08:42:03 PM »
if a DCL can't be found? Saves having a wrapping if statement.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Abort and return to command prompt
« Reply #4 on: August 08, 2012, 08:53:58 PM »
There is a difference in functionality :

.NET return
returns control to the calling method and can optionally return a value.

the lisp (exit)
returns the error message quit/exit abort and quits to the AutoCAD Command prompt.
.... it's handy to have a good *error* routine so that the environment will be cleaned up.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

BlackBox

  • King Gator
  • Posts: 3770
Re: Abort and return to command prompt
« Reply #5 on: August 08, 2012, 10:25:23 PM »
As Kerry has suggested, I use a localized *error* sub-function for Commands that either change settings, or create external objects that must be released, in addition to ending an undo mark when applicable.

In combination with, or in lieu of, I usually use some sort of test function (IF + AND being my most common) to only perform the minimal task(s) necessary before the automated portion of my code. Less to 'handle' if the user hits escape.

HTH
"How we think determines what we do, and what we do determines what we get."

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Abort and return to command prompt
« Reply #6 on: August 09, 2012, 03:24:37 AM »
You could use the vl-exit-with-value to get something similar to C#/C++'s return keyword. Unfortunately though it only works from inside a compiled VLX using a separate namespace (if you use it inside the document namespace - i.e. a same namespace VLX or a FAS/LSP file - it acts like exit but without calling the *error* function or returning a value)  :| ... why that should be you'd have to ask ADesk. My guess is it "exits the namespace, rather than the defun". Same goes for the vl-exit-with-error it seems. At least from my quick tests here in Vanilla 2012:
Code - Auto/Visual Lisp: [Select]
  1. (defun test1 ()
  2.   (vl-exit-with-value "testing vl-exit-with-value")
  3.   1)
  4.  
  5. (defun test2 ()
  6.   (vl-exit-with-error "testing vl-exit-with-error")
  7.   2)
  8.  
  9. (defun c:test (/ *error*)
  10.   (defun *error* (msg) (princ "\nError:\t") (princ msg) (princ))
  11.   (princ (test1))
  12.   (princ (test2))
  13.   (princ))
Both those simply exit to command prompt without returning anything or calling the localized *error* defun at all.

I'd go with Kerry & RM's idea though! There's nothing worse than a user finding his OSnaps turned off after using your custom command. Even in C#/C++ you need to watch for this. If your defun doesn't alter stuff which should revert back, then you may not need to exit cleanly - but there's many times that you'd set some sysvar to make your programming work less or to make the user-interface more to your liking. In which case an error-handler is an absolute MUST.

Actually there's some debate about the use of return / break to stop a function / loop halfway through (even in C/C++/C#). Some deem it a form of "lazy programming". Their main gripe is exactly this "cleanup" idea - though they tend to use memory leaks as an example (which is less of an issue in lisp).

E.g. If your C function allocates memory dynamically (say using malloc or in C++ new) you should either return the pointer to that allocated memory or release it using free / delete. It just becomes very easy to forget to do so if you use return / break somewhere halfway through your code. I mean you look through your code and see that you've written the free / delete so memory shouldn't "leak". But you miss the line where you return / break earlier from the function / loop - if that return/break is reached the memory is never de-allocated, making your function eat RAM every time it's used.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Abort and return to command prompt
« Reply #7 on: August 09, 2012, 08:05:59 AM »
I find it a rare occasion that I need EXIT?

Ditto, I can't remember ever using it...

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Abort and return to command prompt
« Reply #8 on: August 09, 2012, 10:39:06 AM »
Many years ago Tony and I argued in a very long thread about using (exit). I think that was on the AutoCAD discussion groups, but maybe it was on CompuServe. I use (exit) frequently, or at least I used to when I still wrote a lot of lisp functions.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Abort and return to command prompt
« Reply #9 on: August 09, 2012, 10:39:45 AM »
Somewhat contrived use of (exit):

Code: [Select]
(defun _Document_Has_XRefs ( document / result )

    (vl-catch-all-apply
        (function
            (lambda ( )
                (vlax-for block (vla-get-blocks document)
                    (if (eq :vlax-true (vla-get-isxref block))
                        (progn
                            (setq result T)
                            (exit)
                        )
                    )
                )
            )       
        )       
    )

    result

)

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Abort and return to command prompt
« Reply #10 on: August 09, 2012, 10:44:37 AM »
Quote
but maybe it was on CompuServe.
Now you are showing your age.  8-)
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.

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Abort and return to command prompt
« Reply #11 on: August 09, 2012, 11:30:23 AM »
I usually have a lot of "stuff" going on in the LISP functions, and trying to write error handlers to clean up everything everywhere is somewhat tedious (I use a global handler plus standardized handling for for general clean-up).  So I reserve (exit) calls to signal the somethings-REALLY-wrong-here happenings.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Abort and return to command prompt
« Reply #12 on: August 09, 2012, 12:57:35 PM »
I'm in agreement, exit may be used - it exists after all. It's just that you need to take note that stuff not handled by the garbage collector needs to be handled in the error handler. Whether you create a localized *error* or a common global version is your choice - as long as you don't run into situations like sysvars staying with temporary values, or vla-SelectionSets not deleted, or external ActiveX objects not released - those need to be handled by your error routine(s) if you do use exit. I'd actually say they need to be handled even if you don't use exit - it's just safer that way.

For me, the exit is rather useless - it's more like the abort / exit functions of C++. If it worked exactly as the C return keyword works, then it might have been more useful. As it stands, exit means (to me at least) that something's gone wrong and I need to cancel everything (exactly as if the user pressed ESC).
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

BlackBox

  • King Gator
  • Posts: 3770
Re: Abort and return to command prompt
« Reply #13 on: August 09, 2012, 01:02:48 PM »
As it stands, exit means (to me at least) that something's gone wrong and I need to cancel everything (exactly as if the user pressed ESC).

... And this is where I chose to rely on *error* instead, as if the user pressed ESC, then anything needing to be handled (i.e., sysvars, external objects, etc.) are handled regardless.

For successful completion of code execution I send (*error* nil), whereas 'if' certain criteria is not met first, a CONDitional 'else' expression is used to report to the user what they did wrong (also using *error*, simply changing the MSG argument).
"How we think determines what we do, and what we do determines what we get."

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #14 on: August 09, 2012, 01:05:30 PM »
What I am doing is checking a value for inserting a switch in vertical space.  What I needed was a way to tell the operator they attempted to insert a part below the NESC safety clearance.  Here is the code

Code: [Select]
(if (= (strcase BsHgt) "LOW")
    (progn
      (if (< *LOWBUS* 98)
   (progn
     (aLERT "Too Low!")
     (exit)
   )
      )


    )
  )


Now that we have mentioned the error routine, I dont have one.  I rarely write in LISP, so I could use good examples.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #15 on: August 09, 2012, 01:07:02 PM »
the above could be combined using the LISP version of AND, once I learn how
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Abort and return to command prompt
« Reply #16 on: August 09, 2012, 01:12:45 PM »
Somewhat contrived use of (exit):

Code: [Select]
(defun _Document_Has_XRefs ( document / result )

    (vl-catch-all-apply
        (function
            (lambda ( )
                (vlax-for block (vla-get-blocks document)
                    (if (eq :vlax-true (vla-get-isxref block))
                        (progn
                            (setq result T)
                            (exit)
                        )
                    )
                )
            )       
        )       
    )

    result

)

Cheers.
I think this would always return nil. Seeing as the first block in the blocks collection would be the model space - which isn't an xref. And thus the exit is called on the first block. Though you do mention it's a contrived usage  ;)

Edit:
*allowing time for post edit before posting correction*
Sorry ... yes I missed the progn when reading this.  :-[ Stupid of me. Sorry MP! It's novel I must say!
« Last Edit: August 09, 2012, 01:31:01 PM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #17 on: August 09, 2012, 01:14:39 PM »
do you have a non-vlisp example?  I haven't learned all the Vlisp commands
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Abort and return to command prompt
« Reply #18 on: August 09, 2012, 01:20:59 PM »
I think this would always return nil. Seeing as the first block in the blocks collection would be the model space - which isn't an xref. And thus the exit is called on the first block.

*allowing time for post edit before posting correction*

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #19 on: August 09, 2012, 01:31:51 PM »
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Abort and return to command prompt
« Reply #20 on: August 09, 2012, 01:48:50 PM »
do you have a non-vlisp example?  I haven't learned all the Vlisp commands
Here's  simplistic idea to show something which happens quite often:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:DrawOneLine  (/ pt1 pt2 osmode cmdecho *error*)
  2.   (defun *error*  (msg)
  3.     (and osmode (setvar "OSMODE" osmode))
  4.     (and cmdecho (setvar "CMDECHO" cmdecho))
  5.     (cond ((not msg))
  6.           ((wcmatch (strcase msg) "*EXIT*,*ABORT*,*QUIT*"))
  7.           (t (princ msg)))
  8.     (princ))
  9.   (if (and (setq pt1 (getpoint "Pick line's start point: "))
  10.            (setq pt2 (getpoint pt1 "Pick line's end point: ")))
  11.     (progn (setq osmode  (getvar "OSMODE")
  12.                  cmdecho (getvar "CMDECHO"))
  13.            (setvar "OSMODE" 0)
  14.            (setvar "CMDECHO" 0)
  15.            (command "_.LINE" pt1 pt2 "")))
  16.   (*error* nil))
There are better way to write the above. But it serves much like RenderMan's situation - i.e. use the *error* routine to clean up even if there was no error.

Say the above is started transparently during another command. The line command would fail with a "Function canceled" error message. The *error* defun would still ensure that osmode & cmdecho are reset back to what they were.

Also if the user presses ESC (or you add an exit, perhaps due to a point not inside a defined area) that message won't be displayed on the command-line. If you want it displayed then omit that wcmatch line, or modify for other messages.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Eddie D.

  • Newt
  • Posts: 29
Re: Abort and return to command prompt
« Reply #21 on: August 09, 2012, 01:58:15 PM »
Not related to your topic, CMDRDUH, but it's good to see someone else on The Swamp that does substation design!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Abort and return to command prompt
« Reply #22 on: August 09, 2012, 04:20:17 PM »
the above could be combined using the LISP version of AND, once I learn how

Perhaps something like this David

Code - Auto/Visual Lisp: [Select]
  1.  
  2.         (= (strcase bshgt) "LOW")
  3.         (< *LOWBUS* 98)
  4.     )
  5.     (progn
  6.         (alert "Too Low!")
  7.         (exit)
  8.     )
  9. )
  10.  
  11.  

Just yell if you need help

Stay well,
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Abort and return to command prompt
« Reply #23 on: August 09, 2012, 04:25:05 PM »
Thats the ticket Kerry! thanks.  I knew it would be easy.  I am still thinking in .Net and cant remember the old LISP ways.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Abort and return to command prompt
« Reply #24 on: August 09, 2012, 05:22:17 PM »
Here is how I might code it:

Code - Auto/Visual Lisp: [Select]
  1.     (   (and (= (strcase bshgt) "LOW") (< *LOWBUS* 98))
  2.         (alert "Too Low!")
  3.     )
  4.     (   t
  5.         <Rest of Program>
  6.     )
  7. )

This avoids the need to use exit to force an error since the program will cease evaluation of the cond expression when a test expression returns a non-nil value. Of course, in this particular case where there is only a single condition to be tested, an if expression could also be used in place of the cond expression, however, usually there is more than one error condition to be checked, and so cond becomes more suitable (and readable) than multiple nested if statements.

In fact, I use this construct in almost all of my programs which utilise DCL, as, in my opinion, it is cleaner than using exit, doesn't necessarily require an *error* handler, and furthermore retains the flow of the code (i.e. the program is being evaluated line by line rather than aborting).

My 2p  :-)

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Abort and return to command prompt
« Reply #25 on: August 09, 2012, 06:21:52 PM »
Here is how I might code it:

Code - Auto/Visual Lisp: [Select]
  1.     (   (and (= (strcase bshgt) "LOW") (< *LOWBUS* 98))
  2.         (alert "Too Low!")
  3.     )
  4.     (   t
  5.         <Rest of Program>
  6.     )
  7. )

I think this makes code more readable:

Code - Text: [Select]
  1. (if (and (= (strcase bshgt) "LOW") (< *LOWBUS* 98))
  2.   (progn (alert "Too Low!") (exit)))
  3.  
  4. (if (failed-p (test1))
  5.   (exit))
  6.  
  7. (if (failed-p (test2))
  8.   (exit))
  9.  

I want the error condition to cause an immediate failure without getting propagated and without being hidden intside a fancy structure (or indented 20 spaces), and I want it to be obvious when scanning the code 30 years later what the control flow is here.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Abort and return to command prompt
« Reply #26 on: August 09, 2012, 06:33:28 PM »
I shan't argue with your evident programming expertise Owen and I respect your opinion, but I can't say that this structure:

Code - Auto/Visual Lisp: [Select]
  1. (if (failed-p (test1))
  2.     (progn
  3.         (princ "\nTest1 failed.")
  4.         (exit)
  5.     )
  6. )
  7.  
  8. (if (failed-p (test2))
  9.     (progn
  10.         (princ "\nTest2 failed.")
  11.         (exit)
  12.     )
  13. )
  14.  
  15. (if (failed-p (test2))
  16.     (progn
  17.         (princ "\nTest1 failed.")
  18.         (exit)
  19.     )
  20. )

is any more readable than:

Code - Auto/Visual Lisp: [Select]
  1.     (   (failed-p (test1))
  2.         (princ "\nTest1 failed.")
  3.     )
  4.     (   (failed-p (test2))
  5.         (princ "\nTest2 failed.")
  6.     )
  7.     (   (failed-p (test3))
  8.         (princ "\nTest3 failed.")
  9.     )
  10. )

I don't think the level of indentation plays any part since both would have to be indented to the level at which the conditions are to be tested in any case.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Abort and return to command prompt
« Reply #27 on: August 09, 2012, 10:21:29 PM »
< .. >
I want the error condition to cause an immediate failure without getting propagated and without being hidden intside a fancy structure (or indented 20 spaces), and I want it to be obvious when scanning the code 30 years later what the control flow is here.

I concur !


I shan't argue with your evident programming expertise Owen and I respect your opinion, but I can't say that this structure:

Code - Auto/Visual Lisp: [Select]
  1. (if (failed-p (test1))
  2.     (progn
  3.         (princ "\nTest1 failed.")
  4.         (exit)
  5.     )
  6. )
  7.  
  8. (if (failed-p (test2))
  9.     (progn
  10.         (princ "\nTest2 failed.")
  11.         (exit)
  12.     )
  13. )
  14.  
  15. (if (failed-p (test2))
  16.     (progn
  17.         (princ "\nTest1 failed.")
  18.         (exit)
  19.     )
  20. )

is any more readable than:

Code - Auto/Visual Lisp: [Select]
  1.     (   (failed-p (test1))
  2.         (princ "\nTest1 failed.")
  3.     )
  4.     (   (failed-p (test2))
  5.         (princ "\nTest2 failed.")
  6.     )
  7.     (   (failed-p (test3))
  8.         (princ "\nTest3 failed.")
  9.     )
  10. )

I don't think the level of indentation plays any part since both would have to be indented to the level at which the conditions are to be tested in any case.

Lee, You're assuming the assertion tests can all be collected together.
I've never had a situation where that can be achieved that I recall.
... Particularly when dealing with code that is any considerable length.

Regards
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Abort and return to command prompt
« Reply #28 on: August 09, 2012, 10:27:16 PM »

Just for an option.
This is really old .. and it is called innumerable times each day.

Code - Auto/Visual Lisp: [Select]
  1.  
  2. ;;;------------------------------------------------------------------
  3. ;;;------------------------------------------------------------------
  4. ;;;
  5. ;;; Spit the Dummy if 'testStatement evaluates to nil
  6. ;;; argument must be quoted
  7. ;;;   (setq var 0)
  8. ;;;   (KDUB:assert 'var "Symbol 'VAR' has no value assigned.")
  9. ;;;   (KDUB:assert '(not(zerop var)) "Symbol 'VAR' evaluates to 0 ... this is illegal ... go to jail")
  10. ;;;   (KDUB:assert '(> var 0) nil)
  11. ;;;   (KDUB:assert '(< var 1) nil)
  12. (defun kdub:assert (teststatement message)
  13.   (if (not (eval teststatement))
  14.     (progn (kdub:display-message
  15.              " **** Assertion Failure"
  16.              (if message
  17.                message
  18.                (list (vl-prin1-to-string teststatement) " ==>> nil/null")
  19.              )
  20.            )
  21.            ;; decide what to do here later ?
  22.            (if kglobal:debug_on
  23.              (princ "  ")
  24.              (exit)
  25.            )
  26.     )
  27.   )
  28.   (princ)
  29. )
  30. ;;;------------------------------------------------------------------
  31. ;;;------------------------------------------------------------------
  32.  
  33.  
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Abort and return to command prompt
« Reply #29 on: August 09, 2012, 10:45:47 PM »

This goes with that :)

Code - Auto/Visual Lisp: [Select]
  1.  
  2. ;;;------------------------------------------------------------------
  3. ;;;
  4. ;;; (KDUB:display_formatted_message prefix mess )
  5. ;;; kwb 20020715
  6. ;|
  7. prefix : String or nil
  8. mess   : atom or list comprising STRing, INT, REAL,
  9.          SYMbol, ENAME, VLA-OBJECT, FILEid etc
  10. |;
  11. ;;;
  12. ;;; Print a formatted message to the command line
  13. ;;;
  14.  
  15. (defun kdub:display-message (prefix mess)
  16.           (list "\n"
  17.                 (if (= (type prefix) 'str)
  18.                   prefix
  19.                   "; **** ERROR"
  20.                 )
  21.                 ": "
  22.           )
  23.   )
  24.   (if (vl-consp mess)
  25.     (mapcar 'princ mess)
  26.     (princ mess)
  27.   )
  28.   (princ)
  29. )
  30.  
  31. ;;;------------------------------------------------------------------
  32. ;;;------------------------------------------------------------------
  33.  

.. thanks John boy :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Abort and return to command prompt
« Reply #30 on: August 09, 2012, 11:10:19 PM »
I don't think the level of indentation plays any part since both would have to be indented to the level at which the conditions are to be tested in any case.

In these contrived examples I can't disagree, but in a real application, IMO the indentation does become a factor because you inevitably have to nest multiple levels deep.

In your example, it's easier for someone to append code in the future after the (cond) without realizing that the appended code executes even during failure conditions. That's what I meant about "hiding" assertions inside a structure. There is no wrong way or right way, necessarily, but I think there is an unwarranted stigma to using (exit), and I hope you don't dismiss it out of hand. Part of my motivation is to dispel any myth that (exit) is a kludge that "real" programmers avoid.

BlackBox

  • King Gator
  • Posts: 3770
Re: Abort and return to command prompt
« Reply #31 on: August 10, 2012, 02:20:19 AM »
I do not feel that there is any stigma for or against using Exit; rather it's more likely that most simply use the best tool for the job at hand (which ends up not being Exit).

Most Visual LISP routines incorporate a change in sysvar, or external object which warrants a better option than Exit. In my limited experience, it is rare that I code a routine where Exit would be sufficiently effective.
"How we think determines what we do, and what we do determines what we get."

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Abort and return to command prompt
« Reply #32 on: August 10, 2012, 02:56:40 AM »
Usually ... when a function becomes so large that a cond structure becomes "lost" and/or obscured ... causing you to need exit: This means your function is too convoluted, at least for Lisp-best-practise. I've seen some, and I've written some myself (most notably my AutoIncr's main input function - from line 1657 here  :-[ - "when" I get the time I'm definitely going to re-write that, at the very least, into separate functions).

In the above AutoIncr sample I'd have to follow a method like MP's example in order to use the exit function - since I don't want the calling function to exit, only the current one. Which IMO might even make than function more convoluted, therefore the cond used is the best for that case. Though the contents of each cond makes the function lumber-some (never mind cumbersome). So in the "lisp-way" (though many languages advocate keeping each function minimal for ease of future support) would be to effectively extract each condition body into a separate defun of its own - then the condition would simply call that defun instead of inlining its code. That would make the cond structure a lot more readable for future edits.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.