14
We currently can only pass

by copy a.k.a. by value, or
by modifiable reference (var).

Passing by copy is problematic for things that are expensive to copy and which only need to be observed by the called function. This can range from strings to complete records. Why waste CPU cycles copying?

Passing by modifiable reference if the arg should not be modified is wrong semantically and opens us up to accidents later. It is especially bad if designing public API, because then a user will assume they can modify the argument, and/or that doing so has any effect. It is also not much better in internals because there is no way to document it except comments: 'this is passed by var for speed', etc. - one of which I have seen in MS base code!

So if we pass by modifiable var but say 'you should not modify this, although you can...', that is unimpressive and a ticking time bomb until some callee does something with the argument that interferes with or outright breaks anything/everything after the call.

***

Other languages such as C++ that have the option of passing by reference allow to pass by reference-to-constant, i.e. const& in that case. This avoids copying the argument by passing by reference but ensures and self-documents that the receiving callee cannot modify it at all. Thus, we get the ideal balance of efficiency and proper API declaration/restriction.

Please, please consider adding something like this to AL, e.g. const var in receiving functions.

***

(Perhaps this could also be accompanied by some way to make local values const after initialisation, but that seems far less important than preventing copying or accidental modification of references.)
Category: Development
STATUS DETAILS
Needs Votes

Comments

D

Following discussion in which it seemed to cause confusion, I should point out that declaring something as `const var` in a receiving function should mean that the compiler should enforce, at build time, that the function cannot assign to the variable, cannot call modifying methods on it, cannot pass it to another function that only receives by non-const `var`, etc. Someone said it would cause runtime slowdown, but I don't want any runtime checks, nor can I fathom why they thought any would need to exist. [shrug]

Category: Development

D

I thought about this a little more. This request assumes the BC platform doesn't implement any kind of copy-on-write optimisation. If it did, then obviously records/strings/whatever that never actually get modified by the receiving function won't incur the overhead of copying, if they effectively have reference semantics until some change is made on them.

Does BC use anything like that under-the-hood? IIRC the generated C# might've used the same types for records but with an instance property for whether or not they were `var`, but I might be misremembering or oversimplifying.

In any case, either BC already doesn't incur full copy overhead for every non-`var` argument of non-trivial type, in which case that should be documented to avoid paranoid folk like me worrying about it... or it does, in which case there should be a way to squash that, i.e. `const var` for purely observing functions.

Category: Development

D

( originally posted as https://github.com/microsoft/AL/issues/5989 )

Category: Development