Jump to content

Order of function definitions inside an "overall" definition.


JerryFiedler

Recommended Posts

Is there an issue with the order of the definitions within a function definition that contains other definitions?

Example.lsp

(defun Main ( / )

 

     (One x y z)

 

     (Two a b c)

 

         (defun One (x y z / )

         

         ) end One

 

         (defun Two (a b c / )

 

         ) end Two

) end Main

 

 

In this example One and Two are called before the definitions in the Main definition.

Should One and Two be physically located above the calls? (Such as immediately after the line (defun Main.....)?

Another related question: Are definitions INSIDE other definitions (as in this example) localized? 

If I want them localized do I add their names to the (defun Main ( / here ))?

What is good practice?

Thank you for taking the time to read this post and hopefully provide your thoughts.  I was unsuccessful searching the web. It seems I could not come up with good search terms.

 

Link to comment
Share on other sites

1 hour ago, JerryFiedler said:

In this example One and Two are called before the definitions in the Main definition.

Should One and Two be physically located above the calls? (Such as immediately after the line (defun Main.....)?

 

Did you try to evaluate the code? If so, you would have answered your own question - the function must be defined before it is evaluated, else the interpreter will report a 'no function definition' error. That's not to say that it has to be the first expression within the outermost defun expression, but only that it must be defined before the function is evaluated, e.g.:

 

(defun main ( / a )

    (setq a 2.0)

    (defun foo ( x )
        (+ x 2)
    )
    (foo a)
)

 

1 hour ago, JerryFiedler said:

Another related question: Are definitions INSIDE other definitions (as in this example) localized? 

If I want them localized do I add their names to the (defun Main ( / here ))?

What is good practice?

 

Unless the symbols used to represent the functions are declared local to the outer defun expression, they will be defined within the document namespace (with the same scope as the outer defun, or as a global variable); declaring such symbols as local to the function in which they are defined will restrict the scope of their definition to that function, with the symbols reverting to their previous value outside of the scope of the function (which will likely be nil, but not necessarily).

 

Observe the following:

(defun foo ( x )
    (+ x 3)
)

(defun main ( / a foo )

    (setq a 2.0)

    (defun foo ( x )
        (+ x 2)
    )
    (foo a)
)

 

_$ (foo 2.0)
5.0
_$ (main)
4.0

 

This highlights a potential issue where function naming conventions are concerned and motivation for declaring functions as local to the function in which they are evaluated, since commonly named functions may otherwise overwrite each other's definitions within the document namespace (in the same way that global variables may be overwritten).

 

The drawback to declaring a function as local is efficiency, as the function is redefined with every evaluation of the function in which it is locally declared.

Edited by Lee Mac
  • Thanks 1
Link to comment
Share on other sites

Lee, Thank you very much for your response.  So in my example I would just move the One and Two definitions to before their calls. Simple and I will always format that way.  Since their names are not in the "local" list they would be global and be available to some other third routine.  Being global is not what I would actually want since those internal defun's are usually very specific to the calling routine and not usually general in nature.

Now assume I load my "Example.lsp" but do NOT execute function Main.  Are functions One and Two still available to a third routine even though Main was not executed?  In other words, did simply loading the lisp file make EVERY defun statement within the file available regardless of whether or not the definition is nested?  (Assuming they were not specifically localized.)

 

Link to comment
Share on other sites

13 minutes ago, JerryFiedler said:

Now assume I load my "Example.lsp" but do NOT execute function Main.  Are functions One and Two still available to a third routine even though Main was not executed?  In other words, did simply loading the lisp file make EVERY defun statement within the file available regardless of whether or not the definition is nested?  (Assuming they were not specifically localized.)

 

No, functions One & Two will only be defined when their respective defun expressions are evaluated, and such defun expressions will only be evaluated when the function Main is evaluated. When loading an AutoLISP file, the contents are merely evaluated as if they were pasted to the command line or console - the interpreter does not 'scan' for nested function definitions - in fact, the interpreter is entirely indifferent to the expressions being evaluated: you could happily load an AutoLISP file containing only princ expressions without defining any functions whatsoever.

  • Thanks 1
Link to comment
Share on other sites

Lee,  Thank you again.  Your explanation is very clear and greatly appreciated.  I am going to review all of my lisp files/functions to make sure they are formatted correctly to avoid conflict.  I usually take care when naming functions to not create conflicts but that can be difficult.  Localizing where appropriate sounds like a good idea.

Link to comment
Share on other sites

If I understand correct you have some common functions that you want to use in various code so you can check did I already load it in another program.

 

Like Lee this has to occur at the right spot in your "Main" defun but its very simple.

 

(if (not AH:Toggs)(load "Multiple toggles.lsp")) ; this is say near top of "main" loads the lisp if not already loaded it has some local variables defined

(setq ans (reverse (ah:toggs   '("A B C D" "A" "B" "C" "D")))) ; somewhere in code choose A B C or D

 

So I have small what I call Library routines so don't cut and paste code into all my other code and I know it works. Working on excel link.lsp as a library function, an example out there is getexcel.lsp.

 

Edited by BIGAL
Link to comment
Share on other sites

Bigal,  Thank you for your comments. The questions I had, and Lee has answered, were raised more for "where" the defun's should be located rather than "how" or "when" to load as your post suggests.  I have what I call "stand-alone" routines that I either load or autoload with my acaddoc.lsp.  I find that using autoload works best for me.  For years I used your method for all my command buttons.  When I learned how to use the acaddoc.lsp I changed all of the macro buttons to just the function name.  Much cleaner in my opinion.  Of course, everyone has their own preferences.

My main concern is conflict between function names.  For functions that only apply to the Main function, in my terms "nested" functions, and have no use outside of the Main routine I am going to localize their definitions.  I will simply move them to the beginning of the Main code and add their names to the local variable list.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...