Hi Rowan,

> On Aug 25, 2024, at 11:31, Rowan Tommins [IMSoP] <imsop....@rwec.co.uk> wrote:
> 
> 3) The expression should be passing additional information into the function, 
> not pulling information out of it. The syntax shouldn't be a way to write 
> obfuscated reflection, or invert data flow from callee to caller.
> - No assignments.
> - No ternaries with "default" on the left-hand side - "$foo ? $bar : default" 
> is acting on local knowledge, but "default ? $foo : $bar" is acting on 
> information the caller shouldn't know
> - Same for "?:" and "??"
> - No "match" with "default" as the condition or branch, for the same reason. 
> "match($foo) { $bar => default }" is fine, match(default) { ... }" or 
> "match($foo) { default => ... }" are not.


I think this brings up a good question on what exactly should be intended to be 
public API. Currently, there's two main ways to effectively write a default 
parameter:

        function foo(int $param = 42) {}
        function bar(?int $param) { $param ??= 42; }

In the former, the default value is listed in the function declaration, along 
with the function name, and parameter type and name, which are already part of 
the public interface.
In the latter, the default value is an implementation detail of the function, 
and is not part of the function declaration.

(You could also ?int $param = 42, but I'd argue that at that point, if you 
really need to distinguish among the set of (unspecified, null, value), you're 
better off with an ADT, which we don't have yet. And you can also explicitly 
expose a default value as a static value on a type, when a function itself 
doesn't want to/shouldn't make the policy decision of what the default is.)


Although I'm not sold on the idea of using default as part of an expression, I 
would argue that a default function parameter value is fair game to be read and 
manipulated by callers. If the default value was intended to be private, it 
shouldn't be in the function declaration.

One important case where reading the default value could be important is in 
interoperability with different library versions. For example, a library might 
change a default parameter value between versions. If you're using the library, 
and want to support both versions, you might both not want to set the value, 
and yet also care what the default value is from the standpoint of knowing what 
to expect out of the function.

-John

Reply via email to