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