Jump to content

Declaring Local Variables & Arguements for sub functions


Recommended Posts

Posted

I expect all you experienced will find this question really easy, but here goes:

 

I'm confused as to what should be declared in the ( / ) after the define functions in the two variations of code. Should it be (a / b) in both cases? Neither?

 

This code has the subfunction OUTSIDE the main function

(defun c:main_f ( / a )
 (alert "\nThis is the main_f")
 (setq a "\nThis is from the main_f")
 (sub_f)
 (alert "This is the main_f again")
 (alert b)
 (princ)
)

(defun sub_f ( a / b)
   (alert "\nThis is the sub_f")
 (alert a)
 (setq b "\nThis is from the sub_f")
 (princ)
)

 

This code has the subfunction INSIDE the main function

(defun c:main_f ( / a )
 (alert "\nThis is the main_f")
 (setq a "\nThis is from the main_f")
 (sub_f)
 (alert "This is the main_f again")
 (alert b)

(defun sub_f ( a / b)
   (alert "\nThis is the sub_f")
 (alert a)
 (setq b "\nThis is from the sub_f")
 (princ)
)
 (princ)
)

Posted (edited)

Both examples are incorrect - you would receive a 'too few arguments' error when evaluating the c:main_f function, as you are not supplying the argument required by the sub_f function.

 

In my opinion, there is no 'correct' answer to this question - the answer depends on the behaviour that you require for the functions, and also your personal coding style (some programmers like to define variables local to one function and reference them in another function evaluated from within the function in which they are defined; others (like myself) prefer to avoid dynamic scoping and instead keep the scope of variables to within the functions in which they are defined).

 

(EDIT: change lexical scoping to dynamic scoping)

Edited by Lee Mac
Posted

Thanks Lee. I was trying to show that variable a is passed to sub_f & variable b is passed back up to main_f with no global variables anywhere.

I wrote the code above very quickly to demonstrate variable passing, not really as a working lisp, although it works now I've change a few things. However I think variable b is global even though vlide doesn't flag it up as such.

(defun c:main_f ( / a )
 (alert "\nThis is the main_f")
 (setq a "\nThis is from the main_f")
 (sub_f)
 (alert "This is the main_f again")
 (alert b)

 (princ)
)  

(defun sub_f ( / )
   (alert "\nThis is the sub_f")
 (alert a)
 (setq b "\nThis is from the sub_f")
 (princ)
)

 

BTW

Lexical Scoping sounds like a board game !

Posted

Apologies, my earlier post should have said dynamic scoping as opposed to lexical scoping: dynamic scoping means a variable may be referenced within all functions evaluated from within the function in which the variable is defined; on the other hand, lexical scoping means a variable is only referenced within the definition of the function in which it is defined.

 

(defun c:main_f ( / a )
 (alert "\nThis is the main_f")
 (setq a "\nThis is from the main_f")
 (sub_f)
 (alert "This is the main_f again")
 (alert b)

 (princ)
)  

(defun sub_f ( / )
   (alert "\nThis is the sub_f")
 (alert a)
 (setq b "\nThis is from the sub_f")
 (princ)
)

 

In this example variable 'b' is global and variable 'a' is referenced within sub_f although defined locally within c:main_f - an example of dynamic scoping.

 

The issue with this approach is that sub_f is now entirely dependent on c:main_f and the two functions must always be defined & used together (i.e. sub_f cannot be used independently as a library function).

 

If sub_f were to be used within another program, it would need to rely on a global variable 'a' (global relative to the scope of sub_f) already being defined and holding valid data - this is the route that I personally avoid.

Posted

In the code above how could I make 'b' local?

 

(i.e. sub_f cannot be used independently as a library function).

I'd not thought of using library functions, what a good idea. I always copy & paste the code in from a previous lisp then amend it accordingly.

Posted
In the code above how could I make 'b' local?

 

It depends on the behaviour you are looking for - you could declare symol 'b' local to c:main_f with no change to the current function behaviour, or you could declare symbol 'b' local to sub_f and use the return of this function to define another variable local to c:main_f.

 

There is no one-size-fits-all solution.

Posted (edited)

Well in the lisp I'm writing atm I'm using two sub-functions neither of which need to return a value to the main function. Either of the sub-functions may be called depending on conditions being met which are decided by the main. However the main function runs within a while loop so that either sub lisp is called multiple times until a right click is performed, then it drops out of the loop & the program ends.

Since the sub-functions may be called multiple times I'd sooner that the variable being passed down was returned to a nil value. I could I suppose write a line in the main just below where the sub-function is called with a:

[/(setq myvar nil)CODE] but this seems sloppy coding to me. I thought that if there's a way to localise myvar so that it returns to null after either of the sub-functions has finished using it, it would be a little more 'proffesional'. Perhaps [code]defun sub-function (/myvar)

or

defun subfunction (myvar/)

Edited by Happy Hobbit
Grammar
  • 1 month later...
Posted
If sub_f were to be used within another program, it would need to rely on a global variable 'a' (global relative to the scope of sub_f) already being defined and holding valid data - this is the route that I personally avoid.

 

Lee - shouldn't a library sub-function be generic in nature as long as the person writing the code keeps the variables used within both the main functions and sub-functions consistent throughout all of their programs? For example, in another thread I started here, I am trying to create a layer. This is intended to be used within multiple main functions. Since each main function creates a different layer, I want my sub-function to use generic variables. The main function defines the specifics for the layer and passes it to the sub-function.

Posted
Lee - shouldn't a library sub-function be generic in nature as long as the person writing the code keeps the variables used within both the main functions and sub-functions consistent throughout all of their programs?

 

View a library function as if it is just another built-in AutoLISP function for which you obviously have no access to the source code. How would you then know how to define the variables within the calling program such that the library function operates as expected?

 

For example, in another thread I started here, I am trying to create a layer. This is intended to be used within multiple main functions. Since each main function creates a different layer, I want my sub-function to use generic variables. The main function defines the specifics for the layer and passes it to the sub-function.

 

Are you passing the layer-specific data to the subfunction as arguments? Or are you relying on global variables (global relative to the scope of the subfunction) already being defined when the subfunction is evaluated?

Posted
View a library function as if it is just another built-in AutoLISP function for which you obviously have no access to the source code. How would you then know how to define the variables within the calling program such that the library function operates as expected?

 

That makes sense.

 

 

Are you passing the layer-specific data to the subfunction as arguments? Or are you relying on global variables (global relative to the scope of the subfunction) already being defined when the subfunction is evaluated?

 

Well...I was trying to pass the variables that are defined in my main function as global variables to the sub-function. Then I was going to localize them in my sub-function.

Posted
Well...I was trying to pass the variables that are defined in my main function as global variables to the sub-function. Then I was going to localize them in my sub-function.

 

Localising them within the subfunction will nullify any value they hold outside of such function.

 

I would suggest passing the relevant values as arguments to the subfunction - see this post to understand how to do this.

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...