Setting IT for the caller, not for local use

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Setting IT for the caller, not for local use

Post by slowmaker » Tue Oct 20, 2020 5:43 pm

A return statement allows me to set the result for the caller of a routine. Is there an equivalent for setting the special local variable 'it' for the caller of my routine?
e.g. is it possible for me to write a function foo() which, when called, sets both 'the result' and 'it' for the caller?

[I did try searching (a bit), but I'll admit I gave up pretty quick on this one; how the heck do you search meaningfully for such a common word as 'it'?
Setting it? set special variable it? put it? gimme it? Almost any search gives a bazillion results, all the early ones obviously not what I'm after soooo I punked out]
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Setting IT for the caller, not for local use

Post by Klaus » Tue Oct 20, 2020 5:59 pm

You can actually do this to fill the variable IT:

Code: Select all

...
put a_value into IT
## or
GET a_value
...
But attention:
IT may change when you least exspect IT! :-)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9580
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Setting IT for the caller, not for local use

Post by dunbarx » Tue Oct 20, 2020 6:24 pm

If I understand your question, does this shed any light? In a button script:

Code: Select all

on mouseUp
   get 42
   test it
   answer it
end mouseUp

on test var
   return var * 2
end test
You can see that the local variable "it" has not changed, so "42" is presented, not "84". But this:

Code: Select all

on mouseUp
   get 42
   test it
   answer  the result
end mouseUp

on test var
   return var * 2
end test
Does give you "84". That is, if any of this is pertinent to your question.
Craig

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 10:31 am

@Klaus: Thanks for the response! Yes, the local nature of 'it' is handy but to be used with caution, I agree.

@Craig: It is pertinent, in that it demonstrates how a handler like 'test' fails to do something I would actually like to be able to do occasionally.

using your example structure, here is some invented syntax to hopefully show what I would like to be able to do:

Code: Select all

on mouseUp
   get 42
   test it
   answer it & colon && the result -- would present 'cool: 84' if the below special variable really worked
end mouseUp

on test var
   if var is a number then
   	set TheCallersIt to 'cool' -- <<<<< I made this TheCallersIt up, doesn't really exist
   else
        set TheCallersIt to 'bogus' -- <<<<< I made this TheCallersIt up, doesn't really exist
   end if
   return var * 2
end test
Hopefully this makes it clearer? I'm curious whether it is possible for a user-defined handler to reach back up the scope chain, so to speak, and set the caller's local 'it' variable, the same way 'get' and some other built-in commands do.

At the moment, I have found no way to do this.

Mind you, I wouldn't want this to be the default, but it would be an interesting option to have; after all, it was useful for some built-ins, it might be useful for custom handlers as well.
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3990
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Setting IT for the caller, not for local use

Post by bn » Wed Oct 21, 2020 11:35 am

Hi slowmaker,

with a little tweaking your pseudocode works.

Code: Select all

-- in button script
on mouseUp
   get 42
   test it
   answer it & colon && the result -- would present 'cool: 84' if the below special variable really worked
end mouseUp

-- in card script
on test @var
   put var into tVar2
   if var is a number then
      put "cool" into var -- <<<<< I made this TheCallersIt up, doesn't really exist
   else
    put "bogus" into var -- <<<<< I made this TheCallersIt up, doesn't really exist
   end if
   return tvar2 * 2
end test
I would not use "it" as a parameter because I stay away from using it except for putting it into a variable. Then work with that variable.
By referencing var with @var the code changes the content of "it".
Again code might get confusing if you work on "it" directly. There are numerous ways to do what you want to achieve besides using "it".

Kind regards
Bernd

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 12:47 pm

Hi, Bernd,

Yep, pass-by-reference works, but having to pass the reference to it doesn't really allow for the same semi-natural language use of the called handler + outcomes. You don't have to pass "it" to "get", or "ask" in order for them to set it, and would probably be annoyed at the clunkiness if you did.
bn wrote:
Wed Oct 21, 2020 11:35 am
Again code might get confusing if you work on "it" directly.
I would have to respectfully disagree here. I do not get confused by the fact that "get" works on "it" directly, nor by similar manipulations by "answer", "'ask", and others that do what I would like to (occasionally) do.

For instance a more readable flow usage-example of the 'test' routine (with notional-but-not-really-existent syntax in place) might be like this:

Code: Select all

on mouseUp
   test 42 
   
   if it is "cool" then
   	answer the result
   else if it is "bogus" then
	answer "That's not a number, dude."
   end if
end mouseUp

on test var
  if var is a number then
   	set TheCallersIt to 'cool' -- <<<<< I made this TheCallersIt up, doesn't really exist
	return var*2
  else
        set TheCallersIt to 'bogus' -- <<<<< I made this TheCallersIt up, doesn't really exist
	return empty
  end if 
end test
This allows usage of "it" as a sort of extra state variable to check immediately after the "test" handler returns (as it does for several built-ins), plus a little more scope for exploring ways to form the "natural language"-like phrasing of concepts. Obviously the writer of such a handler should document very, very clearly that the handler will be fiddling about with "it" (although the user should already know never to leave valuable data in "it" anyway, that caution is stated clearly in LC docs and in threads about "it" usage, like this one).

I'm just a little surprised that this feature isn't available, not rabidly advocating for such a thing. There are certainly many other ways to send multiple channels of information back to a caller; this way would only have offered a caller some more phrasing choices that might be more intuitive in some cases. Given LC's history of offering features which increase the natural feel of much code, the lack of this one is, as I say, just a little surprising.

Actually, what surprises me most is that this discussion hasn't already happened somewhere, and someone hasn't already popped in with a thread link to show that it was hashed over ten years ago, and I just didn't have the search-fu to find it. Ah, well, give them time; this thread is still young :)
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9580
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Setting IT for the caller, not for local use

Post by dunbarx » Wed Oct 21, 2020 2:43 pm

Slowmaker.

It has been unofficial but vigorously recommended practice, since 1987 with HC, NOT to use the local variable "it" longer than to place, er, "its" value into another variable. This dictum has also been applied to "the result".

The reason being that both are ephemeral and so very subject to being immediately changed.

This does not address at all your ideas on how to use LC code flow in interesting ways, it is just a little background.

I assume you know why we often use "42" as the foil in certain discussions. :wink:

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9580
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Setting IT for the caller, not for local use

Post by dunbarx » Wed Oct 21, 2020 2:54 pm

Hi.

Rereading your posts, I am still a little unsure why passing a parameter by reference does not directly do what you asked. Can you post a short pseudocode handler to demonstrate what you wished for?

See the short entries in the dictionary under "pass by reference" and "pass by value". Does not "pass by reference" fully fulfill your original query?

Craig

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 4:10 pm

I assume you know why we often use "42" as the foil in certain discussions. :wink:
I know why *I* consider the number significant; I was a huge HG2G fan from the day - somewhere back in the mid-to-late-80's - that I stumbled onto the first book in my local library. I just always assume someone who uses the number is using it for that reason (and if they aren't, they oughta be).
Rereading your posts, I am still a little unsure why passing a parameter by reference does not directly do what you asked. Can you post a short pseudocode handler to demonstrate what you wished for?
I think the difference comes down to aesthetics; there is no functional difference as far as accessing the caller's 'it', but it places a greater burden on the caller.

My way, they can just call SomeHandlerName with no args at all, or with just the args they care about. They do not have to remember to put the "it" var in the parameter list in addition to whatever they are passing, just to be able to then say "if it is foo then blarg with the result" immediately afterward (and of course "it" should be used immediately afterward, before something else can interfere with "it", as with any of the built-ins that modify "it", and as the docs already clearly warn about; I get it, the dangers of "it", really I do :) )

calling the pass-by-ref way:

Code: Select all

SomeHandlerName parmThatMakesSense1, parmThatMakesSense2, it -- ?? gotta remember to tack it in the explicit parm list somewhere, not self-documented by naming the way the other 2 parms are (or could be).
if it is foo then blarg the result -- this part the same either way
calling my way:

Code: Select all

SomeHandlerName parmThatMakesSense1, parmThatMakesSense2  -- cleaner, all args can be self-documented by naming, both on caller and callee ends
if it is foo then blarg the result -- this part the same either way
I am not showing the handler pseudo-code definition because that isn't the place where this feature would make a noticeable difference; it's the caller that gets benefit from not having to explicitly pass the "it" var.

As hinted at in my other posts, imagine if you had to do the pass-by-ref way with the built-ins that use "it".
Maybe better, imagine if LC now decided that you had to start doing it that way even with the built-ins, after years of being accustomed to calling them without explicitly passing "it" in.
So any code that worked with checking "it" after a call to "get", "ask", "answer" etc would suddenly have to get a bit clunkier, because you would have to explicitly add another arg to all those calls.

To me the notion of

Code: Select all

ask it, "prompt"
is quite noticeably clunkier/clumsier than

Code: Select all

ask "prompt"
especially if you imagine all the many, many places the "ask" would be used.
Whether that little bit of extra clunkiness/typing (many times over!) would bother a person will just depend on the person.

So...convenience. Aesthetics. More phrasing choices for english-like code. Large reduction in specifying a commonly used extra-info feature, if the handler in question gets called a lot.
Basically the same kind of benefits we get from the "the result" feature, just more of them.

Another thought experiment: imagine "the result" was *also* local only, could not be influenced by a handler unless you explicitly passed it by reference. Again, now all of a sudden you've got to pass something in explicitly which would work so much more beautifully, so much more conveniently, if the called routine could only set it for the caller without that extra parm being needed for such a commonly used phrase...

My goodness, I have gone on about this quite a bit, haven't I? I'll stop for a moment or three now :)
[edited: typo]
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Setting IT for the caller, not for local use

Post by FourthWorld » Wed Oct 21, 2020 4:14 pm

slowmaker wrote:
Wed Oct 21, 2020 12:47 pm
...for exploring ways to form the "natural language"-like phrasing of concepts. Obviously the writer of such a handler should document very, very clearly that the handler will be fiddling about with "it" (although the user should already know never to leave valuable data in "it" anyway, that caution is stated clearly in LC docs and in threads about "it" usage, like this one).
What is the value of a language feature that increases its learning requirements?
I'm just a little surprised that this feature isn't available, not rabidly advocating for such a thing. There are certainly many other ways to send multiple channels of information back to a caller; this way would only have offered a caller some more phrasing choices that might be more intuitive in some cases.
One of the reasons Python is among the world's most popular languages if that its designer emphasized from the beginning that there be one best way to accomplish a task, and that way is the one way to do it.

With that principle, there are no "sometimes" rules, and ultimately less to learn.
Given LC's history of offering features which increase the natural feel of much code, the lack of this one is, as I say, just a little surprising.
LiveCode inherited a lot of ambiguity from the mother tongue, HyperTalk, but going forward we see a pattern with the LiveCode team emphasizing features over multiple syntax options for using a given feature.

For example, the ability to sometimes call a function using property syntax (eg "the screen text" vs "screenrect()") introduces at least three cognitive issues:
- you then have to also learn why that only works for functions with 0 or 1 parameters but not with 2 or more;
- it slows down the acquisition of a solid distinction between the nature of a function and a property;
- it slows down code skimming when looking for function calls.

I'm sure the HyperTalk team meant well with that, but for all their good intentions it's ultimately less a feature than an anti-feature.

LC's goals are learnability and readability. Where it may occasionally be "English-like" is simply a happy byproduct rather than a goal.

Programming languages require precision by their nature, designed as they are for communicating with a machine.

Natural languages in general are horribly imprecise, English among the sloppiest of them. Consider how often even highly advanced computational systems like humans misunderstand what is conveyed in natural languages. ;)
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 4:27 pm

breaking my self-imposed break-for-a-moment dictum already; as always, FourthWorld, you provoke thoughts :)
FourthWorld wrote:
Wed Oct 21, 2020 4:14 pm
slowmaker wrote:
Wed Oct 21, 2020 12:47 pm
...for exploring ways to form the "natural language"-like phrasing of concepts. Obviously the writer of such a handler should document very, very clearly that the handler will be fiddling about with "it" (although the user should already know never to leave valuable data in "it" anyway, that caution is stated clearly in LC docs and in threads about "it" usage, like this one).
What is the value of a language feature that increases its learning requirements?
This is the part of your post I'm puzzled by; I'm talking about extending a usage that already exists and is common (I hope!) knowledge in the LC community. How would this extension of an existing feature increase learning requirements?

Is the LC team deprecating it's usage of "it" as an information vector for built-in's like "get", "ask", etc? If so, the rest of your post fits perfectly.

If not, I don't understand why a custom handler being able to influence the caller's "it" is somehow more of a learning requirement than the already existing built-in commands ability to influence the callers "it", which the user has to ...learn... about. Once you know the one, the other is an obvious extension.
[edited: yet another typo]
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7215
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Setting IT for the caller, not for local use

Post by jacque » Wed Oct 21, 2020 5:00 pm

Look at the "return" control structure in the dictionary, which might be what you want if you use the "error" or "value" forms.

return <value> [ for { value | error } ]
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 5:12 pm

OHO! Thanks Jacque! I'll definitely play around with that a bit.

Also, quite embarrassed that I had not yet simply read the 'return' entry!
Doubly so because I actually speculated before posting that there might be some additional keywords to tack on to "return" to modify its behavior, and then forgot to check on it :oops:
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Setting IT for the caller, not for local use

Post by FourthWorld » Wed Oct 21, 2020 5:19 pm

slowmaker wrote:
Wed Oct 21, 2020 4:27 pm
breaking my self-imposed break-for-a-moment dictum already; as always, FourthWorld, you provoke thoughts :)
FourthWorld wrote:
Wed Oct 21, 2020 4:14 pm
slowmaker wrote:
Wed Oct 21, 2020 12:47 pm
...for exploring ways to form the "natural language"-like phrasing of concepts. Obviously the writer of such a handler should document very, very clearly that the handler will be fiddling about with "it" (although the user should already know never to leave valuable data in "it" anyway, that caution is stated clearly in LC docs and in threads about "it" usage, like this one).
What is the value of a language feature that increases its learning requirements?
This is the part of your post I'm puzzled by; I'm talking about extending a usage that already exists and is common (I hope!) knowledge in the LC community. How would this extension of an existing feature increase learning requirements?
If something is "common knowledge" why would it be obvious that "the writer of such a handler should document very, very clearly"?

Perhaps I misunderstood. I thought you were expressing a desire for something that didn't exist, rather than describing something that already does.
Is the LC team deprecating it's usage of "it" as an information vector for built-in's like "get", "ask", etc? If so, the rest of your post fits perfectly.
The "it" local variable is a generic placeholder for values returned by commands, distinct from the explicit assignment required for values returned by functions. Being both temporary and volatile (many things alter "it"), if you need to use the data returned for anything beyond the immediately-subsequent statement it's recommended to put the value of "it" into a variable.

Given how broadly "it" is used, I can't imagine anyone advocating it be deprecated.

This implies an intriguing question, though: why does the xTalk family of languages have both commands and functions?

Maybe "why" isn't the question; we know why: HC was born into a world where Pascal was the recommended language for Mac programming, and Pascal is among the few languages that have functions and commands as distinct handler types.

Maybe the better question would be: What is the benefit of having both commands and functions?

The general distinguishing guidance is that functions return values and commands perform actions. But that breaks down in nearly every app we write, because functions can and often do perform actions, and commands frequently return values.

Maybe if we had to do it all over again this design choice might never have occurred to anyone; the language would have only functions as most languages do, and there would be no need for anything as ambiguously volatile as "it".
If not, I don't understand why a custom handler being able to influence the caller's "it" is somehow more of a learning requirement than the already existing built-in commands ability to influence the callers "it", which the user has to ...learn... about. Once you know the one, the other is an obvious extension.
It seems (and please correct me if I misunderstand; Klaus can tell you I often do <g>) that the proposal here is that "it" remain local in scope but be extended to become the one variable where passing it to another handler is always by reference, rather than leaving that as an option as we do for all other variables.

If that understanding is correct, I would respectfully suggest using the existing mechanisms that allow a handler author to determine which args are values and which are references, so we have clean, flexible rules which we can anticipate using consistently with all variables regardless of their name.

If I misunderstand the request, I have to ask your patience in guiding me to the "aha!" moment in which I'll finally grasp what's being suggested.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

slowmaker
Posts: 47
Joined: Fri Feb 08, 2019 1:53 pm

Re: Setting IT for the caller, not for local use

Post by slowmaker » Wed Oct 21, 2020 5:35 pm

FourthWorld wrote:
Wed Oct 21, 2020 5:19 pm
It seems (and please correct me if I misunderstand; Klaus can tell you I often do <g>) that the proposal here is that "it" remain local in scope but be extended to become the one variable where passing it to another handler is always by reference, rather than leaving that as an option as we do for all other variables.

If that understanding is correct, I would respectfully suggest using the existing mechanisms that allow a handler author to determine which args are values and which are references, so we have clean, flexible rules which we can anticipate using consistently with all variables regardless of their name.

If I misunderstand the request, I have to ask your patience in guiding me to the "aha!" moment in which I'll finally grasp what's being suggested.
No worries :)

And nope, I do not suggest that "it" be extended to be passed always by reference by default.
What I was suggesting is that it would be nice to have the option that is covered by Jacque's response; to specify, by some means, inside a called routine, that the caller's "it" shall be modified.

Man, I think my wording above just got worse instead of better; tell you what, just look at the dictionary entry for return (thanks again, Jacque!). You'll see that, as it turns out, the feature I'm (badly) describing already exists!

The only thing I would have done differently is to allow both "it' and "the result" to be simultaneously set by the called routine, without having to empty one or the other as it currently stands, but still; the existing capability does in fact allow "it" to be set in a caller by the called, which is (whew) what this whole thread was about.

Below is (or should be) working code; not hypothetical:

Code: Select all

on mouseup
    put "can't touch this" into it
    foo
    answer it -- << ha haaaa, yes I can...
end mouseup

on foo
    return "nyah nyaaaaaaaaaaa I can TOO set IT from here!" for value
end foo
The important thing is not to stop questioning. Curiosity has its own reason for existence. - Albert Einstein (LIFE Magazine (1955 may 2), p64)

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”