Home AMX User Forum AMX Technical Discussion

define_function or define_call?

which one should i be using? i'm assuming _function as it was added when netlinx appeared.... are there any specific advantages?

sorry if this is obvious or has already been answered elsewhere, i couldn't seem to find much information on the differences between these two.

thanks
mark

Comments

  • markbsure wrote:
    which one should i be using? i'm assuming _function as it was added when netlinx appeared.... are there any specific advantages?

    sorry if this is obvious or has already been answered elsewhere, i couldn't seem to find much information on the differences between these two.

    thanks
    mark
    It is more or less a matter of programming style. You can generally get the same subroutine generated results with either method.

    A Define_function is designed to make it easy to return some value to another place in the program. ATOI(x) (ASCII to Integer the value of x) is a built-in function as are many others. You can write your own as well.

    A Define_call can modify (return) a value in the form of a global or local variable, but is mostly used to replace repeating code blocks. You might write a call that operates a matrix switcher by passing in the input and output value. It really does not return a value, only formats and sends a command string to an RS232 port.

    I wrote many Axcess programs long before NetLinx so functions were not an option. Writing subroutines with the Define_call is hard habit to break. I once wrote an entire program with functions just to see if I could. There was really no difference in performance, only readability.

    I hope this helps.
  • viningvining Posts: 4,368
    Functions allow you to minimize the use of globals and keep the scope of variables limited to the actually section of code that creates and uses the them. If your value is being assigned to a global it doesn't matter which one you use FUNCTION or CALL but ideally you should only use globals when you absolutely have to, locals when required to with in the scope of its code block and stacks every where else.

    With out using FUNCTIONS who can not manipulate a stack or local variable any where other that the code block that created them where as when using a FUNCTION you can pass a stack_var value from function to function and return the manipulated value back to the section of code that created the stack variable to which the scope of that variable is limited.

    By limiting scope of variables you minimize the chance of other sections of code affecting and changing values that they are not designed to.
  • thanks for all the information people. just what i was looking for!
    mark
  • mpullinmpullin Posts: 949
    An experiment

    Since the context of a define_call contains a string (e.g. DEFINE_CALL 'Autopatch_Routine1' (INTEGER zone, INTEGER src)) you would think you could make calls dynamically e.g.
    CALL "'Autopatch_Routine',itoa(nIndex)" (zone,src);
    
    But no, that line gives you a big fat error. I guess because unlike conventional strings, the strings that identify CALLS are parsed at compile time not at run time.

    When I was first learning NetLinx I used CALLS because they were taught in P1, but now I only use functions. Their syntax is more familiar to me, being a C/Java programmer.
  • Not the case for me. I jumped on the ability to call routines WITHOUT needing the "CALL" keyword as soon as NetLinx came out... :)

    - Chip

    B_Clements wrote:
    I wrote many Axcess programs long before NetLinx so functions were not an option. Writing subroutines with the Define_call is hard habit to break.
  • DHawthorneDHawthorne Posts: 4,584
    When all is said and done, I don't think it matters, except for the return value. I tend to still use DEFINE_CALL when there is no return value to be sent, and DEFINE_FUNCTION when there is. I just have a psychological aversion to a function returning a value I'm not going to use.
  • mpullinmpullin Posts: 949
    I'm sure you're aware of this, but I just wanted to point out for newbies that a function doesn't HAVE to return a value. Simply don't put a return type after DEFINE_FUNCTION. Example:
    DEFINE_FUNCTION CMD_ALL_TP(CHAR cmd[]){ // send command cmd to all touchpanels
        STACK_VAR INTEGER i
        for(i=1; i<= Num_Panels; i++){
    	SEND_COMMAND TouchPanels[i], cmd
        }
    }
    
    You'd call this function just by saying something like CMD_ALL_TP('ADBEEP') in your program.
  • So Dave, when you use something like REMOVE_STRING to remove unneeded stuff at the head of a string, do you insist on having a dummy variable, like Trash$ = REMOVE_STRING...? :)

    - Chip
    DHawthorne wrote:
    When all is said and done, I don't think it matters, except for the return value. I tend to still use DEFINE_CALL when there is no return value to be sent, and DEFINE_FUNCTION when there is. I just have a psychological aversion to a function returning a value I'm not going to use.
  • DHawthorneDHawthorne Posts: 4,584
    Chip Moody wrote:
    So Dave, when you use something like REMOVE_STRING to remove unneeded stuff at the head of a string, do you insist on having a dummy variable, like Trash$ = REMOVE_STRING...? :)

    - Chip
    Nope, this particular affectation doesn't go that far :).
    mpullin wrote:
    I'm sure you're aware of this, but I just wanted to point out for newbies that a function doesn't HAVE to return a value. Simply don't put a return type after DEFINE_FUNCTION. Example:

    Yes, but coming from a C++ background where it is required, I always include it. It's been a continuous battle with me, keeping the differences straight between C++ and NetLinx, because they are just similar enough to throw me off at times. So when NetLinx gives me a choice between a method that converges with C++, I use that. I even terminate lines with semicolons; it's far from necessary (most of the time) in NetLinx, but it's one less habit to break.
  • ROOROO Posts: 46
    newbee 2 / old experiences
    DHawthorne wrote:
    Nope, this particular affectation doesn't go that far :).



    Yes, but coming from a C++ background where it is required, I always include it. It's been a continuous battle with me, keeping the differences straight between C++ and NetLinx, because they are just similar enough to throw me off at times. So when NetLinx gives me a choice between a method that converges with C++, I use that. I even terminate lines with semicolons; it's far from necessary (most of the time) in NetLinx, but it's one less habit to break.

    I appriciate the information.! - my background was C/C++ and little things like semicolans are still importent to me.
    The pass by reference parameter list has bitten me several times when fixing someone else's code, so I really appreciate the ability to isolate where variables are changed. Limiting the scope of a variable has been very handy. imho... :^)
Sign In or Register to comment.