Using '@' to mark pass-by-reference (was Re: synonyms)
Mark Waddingham
mark at livecode.com
Fri Aug 18 09:15:19 EDT 2017
On 2017-07-04 17:39, Ben Rubinstein via use-livecode wrote:
> May I hijack this thread to have another go at promoting my feature
> request for a bit of syntax sugar around parameters which I _think_
> would not have a very deep implementation requirement?
>
> http://quality.livecode.com/show_bug.cgi?id=8945
It is no longer a hijack - I've changed the name of the thread :)
(Although I have hijacked your original post by rewriting the content
slightly - I hope you don't mind too much!)
The underlying problem here is that whether or not an argument passed to
a handler is treated 'by value' or 'by reference' is determined by the
handler at the point it is invoked - not at the point it is called
(remember that the message path means that one call can end up invoking
several handlers as it passes through the message path).
This is the only way it can work at the moment because LiveCode Script
does not require you to explicitly mark arguments that should be passed
by reference - without that bit of information, the only thing you have
to 'trust' is whether '@' is present in the signature of the parameter
in the handler definition *when that handler is actually executed*.
Ben's suggestion (which I think is a really good one - even though I've
not commented on it at all up until now - including the original
enhancement request) is that we use '@' as an explicit marker for
whether an argument should be passed by reference.
I can think of at least one other language which has a similar thing -
C#. C# has both by-ref and by-value - and it requires 'ref' to be used
on arguments to method parameters which are 'by-ref'. It requires this
because C# allows method overloading - you can have two methods in a
class with the same name as long as their parameters are different:
class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
Because C# requires 'ref' on arguments it can disambiguate the call to
'SampleMethod' - SampleMethod(tFoo), SampleMethod(ref tFoo).
[ For more details about this see
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref
]
The weak form of the proposal would not require @ before arguments to
reference parameters, but would require that it is not present before
arguments to value parameters:
command myHandler @xRef, pValue
end myHandler
myHandler tRefVar, tValueVar - fine
myHandler @tRefVar, tValueVar - fine
myHandler [@]tRefVar, @tValueVar - not fine: passing tValueVar by
reference to by-value parameter
The strong form of the proposal would require @ before arguments to
reference parameters:
command myHandler @xRef, pValue
end myHandler
myHandler tRefVar, tValueVar - not fine: passing tRefVar by value to
by-ref parameter
myHandler @tRefVar, tValueVar - fine
The weak form would still allow you to make the 'accidentally passing
the wrong argument to a reference parameter' coding fault, but at least
if you used @ consistently then it would catch the 'passing the wrong
argument to a value parameter' coding fault. The strong form would
eliminate ref-parameter related coding faults entirely.
Even in its weak form, there are a few other fringe benefits:
- we could allow @<literal> to mean: I know this is a by-ref
parameter, but I don't care about what it gets changed to, I just want
it to be <literal> on input
- we could allow 'put x into param(y)' if the y'th argument was marked
with '@'
- if @ is used consistently then it solves the mismatched reference
parameter markings in the message path problem:
group: on myHandler @isRef
card: on myHandler isRef -- oops, I forgot the '@'
> There is a very low risk, in my view, of breaking backwards
Ignoring lexical issues (i.e. @ being allowed in an identifier - which
is only the case because of the way the parameter list of handlers is
parsed - ick!), then the weak form has no backwards-compatibility issues
as far as I can see.
In terms of the lexical issue, then the change would mean that '@' would
become a self-delimiting token - and not be allowed in identifiers.
I can't imagine there is any reasonable code out there which uses '@' in
identifiers, a bit like "'" is also allowed in identifiers - so changing
that is probably 'completely' safe. Indeed, we are already considering
removing various characters from the definition of identifier to allow a
little more flexibility in the symbols we can use (not that I
particularly want to add that many symbols, however I fear that adding a
few more is unavoidable if we want to keep the language ergonomic).
My general feeling is that the weak form is much better than we have
now, but the strong form is actually how things should be. Indeed, as
'by-ref' is a more complicated concept in many ways than 'by-value' it
seems fitting that it should be explicitly marked - especially as if we
were able to move to the strong form, we would eliminate the by-ref
related coding faults - at least insofar as getting a runtime error when
we make a mistake (if not a compile-time error - which we could only do
for private handlers due to the dynamic nature of the message path).
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list