A question about call by reference

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

bwmilby
Posts: 462
Joined: Wed Jun 07, 2017 5:37 am
Contact:

Re: A question about call by reference

Post by bwmilby » Sun Feb 07, 2021 7:23 pm

That is what I was saying. The @ means that you must use a variable when calling the function/handler.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: A question about call by reference

Post by dunbarx » Sun Feb 07, 2021 10:49 pm

Brian.

I get that. My point was "how does the command handler know it is being set up for failure"?

Stepping through the script, with no "@", everything goes swimmingly. You get a "42".

But put the "@" in, and an error is thrown at the call to the command handler back up in "mouseUp". I am just wondering how LC knows about the impending failure. The script again:

Code: Select all

on mouseUp
   put 5 into a
   testhandler testFunction(a)
end mouseUp

function testFunction a
   return 42
end testFunction

--on testHandler a --works
on testHandler @a --fails, before it even is reached
  answer a
end testHandler
Craig

bwmilby
Posts: 462
Joined: Wed Jun 07, 2017 5:37 am
Contact:

Re: A question about call by reference

Post by bwmilby » Sun Feb 07, 2021 11:37 pm

Probably a question for LCMark. I'll try... the type of data that you are passing is immutable and the handler requires a mutable variable. Try it with any other constant and you get the same thing. When the interpreter gets to setting up the call to testhandler, it is trying to create a pointer to a variable being passed in (instead of setting up a copy on write variable which would automatically turn a constant into a mutable variable). I'm sure my words aren't exactly correct, but I think I understand the idea.

The compiler could flag it as an error, but I don't think any parameter checking is done at compile time. Probably something that would make sense to add once (optional) type checking is added.

PlaidFlannel
Posts: 43
Joined: Fri Aug 21, 2020 7:06 pm

Re: A question about call by reference

Post by PlaidFlannel » Mon Feb 08, 2021 12:20 am

Thanks to all who responded.

It appears that the correct answer is that any value returned by a function cannot be used as a reference parameter to a handler.

My hypothesis that the problem was that in one case, the value returned by the function was extracted from an array, while in the other case it was a simple value, turns out to be wrong.

A button with this script fails in both cases, but after removing the "@" in the myHandler formal parameter, both statements succeed.

Code: Select all

on mouseUp
   local tInstanceVariable
   
   put newClassName() into tInstanceVariable
   
   -- both of the following statements cause this runtime error:
   -- Execution error at line 30 (Handler: error in parameter expresion) near "myHandler" char 1
   
   myHandler getBeta(tInstanceVariable)
   myHandler getBread("whole wheat")
   
end mouseUp

function newClassName
   local tObject
   
   put 3.14159 into tObject["mAlpha"]
   put "a very long string" into tObject["mBeta"]
   put true into tObject["mGamma"]
   return tObject
end newClassName

function getBeta pInstanceVariable
   return pInstanceVariable["mBeta"]
end getBeta

function getBread pString -- value parameter
   return "pumpernickel"
end getBread

on myHandler @pString -- reference parameter          -- this is line 31 in this script
   put "Result is" && pString into msg
end myHandler

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: A question about call by reference

Post by bn » Mon Feb 08, 2021 2:30 pm

bwmilby wrote:
Sun Feb 07, 2021 5:31 am
.........
As stated earlier, if you are not changing the value then there is probably not a huge cost since the engine does a copy on write. (In a tight loop with many calls you could achieve some speed gains by explicitly doing a pass by reference since the engine wouldn't need to set up the additional variable that supported the copy on write. I did a quick test and the difference was roughly 10ms for 50,000 calls passing a simple integer without changing the value.)
At times @ can save surprisingly much if the value of the passed variable changes between passing.

As a short experiment:
In the ScriptEditor a tab formats a handler, shiftKey-tab formats the entire script. Formatting an entire script is time intensive.

In script of stack "com.livecode.scripteditor.behavior.editorcommon" of the IDE (access it via Project Browser with "show IDE Stacks in Lists" = checked in Menu "View") make changes to record the time (line 3323)

Code: Select all

command scriptFormat pScope, pDontGroup
   lock screen
   local tScroll, t -- added t
   put the milliseconds into t -- added
   ....
   -- code
   -- code
   ....
   put the milliseconds -t && the milliseconds -- added
   set the vScroll of field "Script" of me to tScroll
   unlock screen
end scriptFormat
Open e.g. the script of stack "RevDataGridLibraryBehaviorsDataGridButtonBehavior" with 11000+ lines of code (again via Project Browser)
or
the script of stack "com.livecode.library.dropbox" 5000+ lines of code

Do "shiftKey-tab" a couple of times. Note the milliseconds it takes

Now change again in stack "com.livecode.scripteditor.behavior.editorcommon" at line 540 handler "private function textFormatLine"

from

Code: Select all

private function textFormatLine pLine, pTextLines, @xPreviousLine
to

Code: Select all

private function textFormatLine pLine, @pTextLines, @xPreviousLine
repeat shiftKey-tab a couple of times and note the milliseconds.

In my testing for 11000+ lines in unchanged version it takes 4600 milliseconds, adding @ it takes 2500 milliseconds
For 5000+ lines 1600 down to 1000+ milliseconds.
That is not bad for a simple "@" added.

These changes to the the IDE are not persistent and next time you open LC they are gone.

Kind regards
Bernd

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: A question about call by reference

Post by bn » Mon Feb 08, 2021 3:00 pm

To make it easier to test passing parameters by reference or without for variables that change in between passing here is a stack to test without fiddling with the IDE as in the example above. Though that is a real world example.

In the stack below you have the option to load some IDE stacks of different length and test 10000 passing of the styledArray of those stacks with or without passing them by reference.
In both cases one char is changed in the styledText array in between passing.

Without change to the variable in between passing the difference between passing with or without reference is negligible.

passingParamsByReference.livecode.zip
(1.81 KiB) Downloaded 175 times

Kind regards
Bernd

bwmilby
Posts: 462
Joined: Wed Jun 07, 2017 5:37 am
Contact:

Re: A question about call by reference

Post by bwmilby » Tue Feb 09, 2021 10:35 pm

Bernd,
That is a not-so-insignificant improvement. I wonder if that would be something to suggest to the team as an improvement? I have not looked at the code in that handler though.
Thanks,
Brian

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: A question about call by reference

Post by bn » Wed Feb 10, 2021 12:19 am

bwmilby wrote:
Tue Feb 09, 2021 10:35 pm
That is a not-so-insignificant improvement. I wonder if that would be something to suggest to the team as an improvement?
Brian,
these are pretty extrem cases in the IDE but they show nicely what @ can do when used in the right place.
Maybe when the team has more time to look at stuff like this I will make a pull-request.

Kind regards
Bernd

PaulDaMacMan
Posts: 683
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: A question about call by reference

Post by PaulDaMacMan » Wed Feb 10, 2021 3:13 am

At times @ can save surprisingly much if the value of the passed variable changes between passing.
The only time I've actually seen someone use this was in UDI's PMD (Play MIDI Data) LCS library that creates MIDI file data from HyperCard "ABC" style musical notation. I did some tests while modifying/dissecting his work, with and without @ symbol, and it did indeed have a significant impact on speed. Of course that was way back about a decade ago (on a mobile Core2Duo) so I'm not sure it would be all that significant now. Probably still very much worth using in certain situations and it's basically carpal-tunnel neutral at only one more character to type.
My GitHub Repos: https://github.com/PaulMcClernan/
Related YouTube Videos: PlayList

Post Reply