Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125288 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 68C1C1A00BD for ; Mon, 26 Aug 2024 19:28:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1724700603; bh=LVhhkOfG0AkJCJIaEfBjKtFvcx/J+trFIWFGJyR4BMQ=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=KYGvu519qRuJEIT8wIEk08prFzx2N0I3PoGAJrKm1SwcZtJVE31pcUS54ldNnE7ni 4e2m7fava3yo1+GtuWYTadywcWCtVT6Om+fzpura+dEXEHUChNr1MaFixMiZA6xmHR ouV14lgsHawNKUl8aTBYuBIvtTf480cTE+iwJVL8qVUUL8vfkBJMMgtaMrR3ZOpwzX vMOKHq6KvHi4ZaqT8VQcOBFx0Me8+lBpqft9/BJmOVzyLlXpGzIwY+uhVQpPbriW9v HkQNFHfIgHXyz10sXP9olm0liGiv/1Kj+vI4tJrgPrqIw894/r7KlvN24+1YByzocb 0dz6qRb4bK9wA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D867A18007B for ; Mon, 26 Aug 2024 19:30:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DMARC_MISSING,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,WEIRD_PORT autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f182.google.com (mail-yb1-f182.google.com [209.85.219.182]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 26 Aug 2024 19:30:01 +0000 (UTC) Received: by mail-yb1-f182.google.com with SMTP id 3f1490d57ef6-e1654a42cb8so4684437276.1 for ; Mon, 26 Aug 2024 12:28:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1724700487; x=1725305287; darn=lists.php.net; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=JVQB2OKMosz0V8w3zUjoXvIvKBKzCk5jE0UpVRo4MoQ=; b=hXIBwNbTDgOTKUTirbWPeGKTHqWEYBTULU1DIwbDkakFgtV70fVdGDFlb5EnkGXuJv QX8SfQbOhTNq5RGMVQ0MlxG/GTxFBx5pTTG5UGPYqcpa/bGPu1DY46xAvw1C6+PR6QaQ pJZz5iIPKIP3q7YSEpmuHsaOLlz13cAGz3WGKbVQoN8z5vQqr80rze1tqxgt9AfPKP4W CKuRt5WQMILp+l+/cY/zukcV8yTz0FVb4iARoUsHKs2FnI4JrZB/yMq9n+NtnjCTobOv 5yeoo86PcrRKQ6+wkX6lqx3G3wuSvSuz0k+jZRW9aRezBcqyjL4y2fqmgzl2q81bkaYx xQ/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724700487; x=1725305287; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JVQB2OKMosz0V8w3zUjoXvIvKBKzCk5jE0UpVRo4MoQ=; b=og4ZNh9+QxvzxahuVsOeuqkmWYad+wtBBDrHZ1NjkC/RBwoAJ7LvNgeS5n+D5sXpoc 5C77AOuQUskTNdIvj+DK8supm2Pq07IlY6IfGCeZSsAmMbkAEFv3EGAd5DAW3HwigRoe q/HJ2i+FyV3TxKkGlxL3N2xz2mgh+JN6IgR+cOLmbZ1tafWk+oCsiJ/FSWu0ajOA7RWe yYhNt3DIPdlrA//yC+VCYxc0LmWmk8SjPoah/1u8Wr8W9rt9EUv5eZMEPTNxw6KtMK6E d6NRy1KNmfUNEP8PqRm2XFPirIjQhFY049AvqqUrWkYs/fNL+pkLN2iUGWeFns7i4+ki FnAw== X-Gm-Message-State: AOJu0YzJ+rUe9U8ACSvY0ymzuHlRl33LH1IAxONdy2ZkyGmbNDbCVV/Y NDULP+9h6qaCwDtwfJ/chx5mhTrHIxTZxHp8EfQZe7OD+sc2E2tMXBdmagisbyd91tkg59XVSjp 1CwY= X-Google-Smtp-Source: AGHT+IGKBFcZlQTP7iScv55VkRm4+4fw1f+FUIdnCLyC97kCA9eVRdM0Pg6IGHRB6kKnrxue1ohMkw== X-Received: by 2002:a05:6902:e10:b0:e0e:af58:f00a with SMTP id 3f1490d57ef6-e1a2a5da203mr608344276.21.1724700487359; Mon, 26 Aug 2024 12:28:07 -0700 (PDT) Received: from smtpclient.apple (c-98-252-216-111.hsd1.ga.comcast.net. [98.252.216.111]) by smtp.gmail.com with ESMTPSA id 3f1490d57ef6-e178e680e42sm2167764276.60.2024.08.26.12.28.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Aug 2024 12:28:00 -0700 (PDT) Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_8CA716FA-2DDB-48BF-B2B0-807F4E32A1D3" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.10\)) Subject: Re: [PHP-DEV] [RFC] Default expression Date: Mon, 26 Aug 2024 15:27:59 -0400 In-Reply-To: <4c3bc918-3aec-4cc5-b342-0924e10949bc@app.fastmail.com> Cc: "Rowan Tommins [IMSoP]" , Larry Garfield , John Coggeshall , Matthew Weier O'Phinney , Bilge To: PHP internals References: <99846F78-38F8-4549-B0A6-6310933AA78D@newclarity.net> <0B974990-05FE-4C46-9C2B-3C243C7E8E81@getmailspring.com> <07E4ABD5-B9CE-47FA-BD9E-E42A82CFC737@newclarity.net> <4c3bc918-3aec-4cc5-b342-0924e10949bc@app.fastmail.com> X-Mailer: Apple Mail (2.3696.120.41.1.10) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_8CA716FA-2DDB-48BF-B2B0-807F4E32A1D3 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Aug 26, 2024, at 8:28 AM, Rowan Tommins [IMSoP] = wrote: >=20 > On Mon, 26 Aug 2024, at 11:43, Mike Schinkel wrote: >>> You ask how a library can provide access to that default, and the = answer is generally pretty trivial: define a public constant, and refer = to it in the parameter definition.=20 >>=20 >> A global? Really? >=20 > I didn't say "global", I said "public". I was imprecise in my description. I meant "global" in the general = programming sense and not in the PHP keyword `global` sense. Sorry about my lack of precision here. > Since you're keen on real-world examples, here's a simplified version = of a real class: >=20 > class ConfigSource > { > private HttpClientInterface $httpClient; >=20 > public const DEFAULT_CONSUL_URL =3D 'http://localhost:8500'; >=20 > public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, ?HttpClientInterface = $httpClient=3Dnull) > { > if ( $httpClient =3D=3D=3D null ) { > $httpClient =3D new HttpClient(); > $httpClient->setRequestTimeoutSecs(5); > $httpClient->setConnectRequestTimeoutSecs(5); > } > $this->httpClient =3D $httpClient; > } > } >=20 > This constructor has two optional parameters; one of them uses a = default which is also referenced explicitly in another class, so is = exposed as a constant; the other uses a completely opaque method of = creating a default object, which even Reflection could not expose. >=20 > The caller doesn't need to know how any of this works to make use of = the class. The contract is "__construct(optional string $consulUrl, = optional ?HttpClientInterface $httpClient)" >=20 > The purpose of the optional parameters is so that you can write = "$configSource =3D new ConfigSource();" and trust the library to provide = you a sensible default behaviour. Thank you (sincerely) for taking the time to author a real-world = use-case. > If it was decided that the code for creating a default HttpClient was = needed elsewhere, it could be refactored into a method, with appropriate = access: >=20 > public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, ?HttpClientInterface = $httpClient=3Dnull) > { > $this->httpClient =3D $httpClient ?? = $this->getDefaultHttpClient(); > } >=20 > public function getDefaultHttpClient(): HttpClient > { > $httpClient =3D new HttpClient(); > $httpClient->setRequestTimeoutSecs(5); > $httpClient->setConnectRequestTimeoutSecs(5); > return $httpClient; > } So, nullable is an equivalent to the union-type concern my discussion = with John Coggeshall uncovered, correct?=20 When two different types can be passed then we cannot depend on the = `default` being a specific type. > Or perhaps the HttpClient becomes nullable internally: >=20 > public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, private ?HttpClientInterface = $httpClient=3Dnull) {} >=20 > Or maybe we allow explicit nulls, but default to a simple class = instantiation: >=20 > public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, private ?HttpClientInterface = $httpClient=3Dnew HttpClient) {} >=20 > None of these are, currently, breaking changes - the contract remains = "__construct(optional string $consulUrl, optional ?HttpClientInterface = $httpClient)". Great example. Now consider the following, assuming the RFC passed but with an added = requirement that `match()` be used exhaustively for nullable parameters = (shown) or parameters type hinted with unions (not shown): $configSource =3D new ConfigSource(default,match(default){=20 NULL=3D>new = ConfigSource->getDefaultHttpClient()->withRequestTimeoutSecs(5), default=3D>default->withRequestTimeoutSecs(5) }) Ignoring that this expression is overly complex, if covering all "types" = would be a requirement in the RFC =E2=80=94 where `NULL` is a type here = for purposes of this analysis =E2=80=94can you identify another breaking = change if the RFC passed? > On Aug 26, 2024, at 8:43 AM, Rowan Tommins [IMSoP] = wrote: > On Mon, 26 Aug 2024, at 11:43, Mike Schinkel wrote: >>=20 >> But saying that we can be certain default values are private and we=20= >> want to keep them that way is provably false by the existence of=20 >> Reflection. =20 > Right now, accessing the default value of an optional parameter is in = the "possible if you mess around with Reflection APIs" set; maybe we do = want to move it to the "is part of the language" set, maybe we don't; = but claiming there is no distinction is nonsense. Now don't go putting words in my mouth, Rowan. ;-) I did not say there was _no_ distinction, I said that we cannot be = *certain* the values are indeed private. Subtle difference I admit, but = there _is_ a difference. :-) > On Aug 26, 2024, at 12:59 PM, Larry Garfield = wrote: > The problem here is that `foo(default | ADDITIONAL_FLAG)` is so far = the most compelling use case I've seen for this feature. It's really = one of only two I see myself possibly using, frankly... >=20 > The other compelling case would be the rare occasions where today = you'd do something like this: > > foo($beep, $user_provided_value ?: default); Is `foo((default)->WithLogger(new Logger));` not a compelling use-case = =E2=80=94 which illustrates the clone of an default initialized object = with injected dependencies with one or a few properties then modified = =E2=80=94 or did you just miss that use-case in the volume of this = thread? > On Aug 26, 2024, at 1:35 PM, John Coggeshall = wrote: > =46rom the example you gave it appears that we can have a concrete = problem when: > 1. There is a parameter with a default value, > 2. That parameter is type-hinted, > 3. The hinted type is declared as a union type, > 4. An earlier version of the library initialized the default with a = value having one of the union types, > 5. End-user developers used the library and then use `default` as an = expression of that type, and finally > 6. The library developer changed the initialization of the `default` = to a different type from the union. > Did I correctly identify the problematic use-case? > Not really. #2 and #3 are irrelevant mixed is actually much more = problematic, I wanted to provide an example that was strongly typed = intentionally to show the problem even when types were explicit. The = relevant portion is #1, #5 and #6. For the purpose of this analysis `mixed` can be considered just a = special case of a union-type where the types available are "all." You say #2 and #3 are irrelevant and mention `mixed`, but if we consider = `mixed` as a special type of union then #2 and #3 become relevant again = (as well as nullable, as Rowan uncovered, which is itself a special type = of union.) Or maybe there are problems with single types that we have not uncovered = yet? > Ok, so for argument sake, what if they revise the RFC to only allow = `default` to be used in an expression when the parameter is not = type-hinted with a union? Would that address your concern? Or are there = other use-cases that are problematic that do not hinge on the parameter = being type-hinted as a union type? >=20 > It wouldn't be enough, offhand it'd also have to be forbidden for = mixed =20 Okay =E2=80=94 with the comment below considered =E2=80=94 then assuming = the RFC were to disallow using `default` as an expression when the = parameter were type-hinted with `mixed` (and when no type hint is used), = what are breaking changes we still need to worry about? =20 Note `default` could still be used with `mixed`, but only by itself, not = in an expression. > (at which point I think the utility isn't there anymore). I think this argument is provably false by the fact that =E2=80=94 = minimally =E2=80=94 the use-case that has resonated with several people = who are otherwise lukewarm has been bitmapped flags, for which type = hinting as `mixed` would be an obvious code smell. But even so, it is up to the RFC author to decide if those limitations = would diminish the utility too much to continue the RFC, and then for = the voters to decide if they agreed with the remaining utility. > On Aug 26, 2024, at 2:11 PM, Matthew Weier O'Phinney = wrote: > There's been a few good lists about the cool things this could enable, = demonstrating the value; maybe now we should focus on the "we absolutely = shouldn't enable" pieces to allow for broader consensus.=20 +1! > On Aug 26, 2024, at 2:49 PM, John Coggeshall = wrote: > Perhaps the answer could be to only allow the use of default when the = assigned default value is a scalar value -- no objects, arrays, enums, = etc (and no mixed )..=20 FWIW, that would eliminate many of the use-cases for me where I see the = feature has value.=20 > On Aug 26, 2024, at 3:12 PM, Bilge wrote: > Whilst this is a curiosity, consider that passing match expressions = directly to arguments is something I personally have never witnessed and = that goes doubly for combining it with `default`. So, whilst it is = interesting to know, and important for the RFC to state the specific = semantics of this scenario, the practical applications are presumed slim = to none >=20 Eh, see nullable and union types (mentioned above.) :-) -Mike P.S. The more I think about this, the more I think that the default = value *should* be a formal part of the function signature. The fact that = has not been explicitly defined before now =E2=80=94 due to the fact it = wasn't relevant before this RFC =E2=80=94 does not automatically require = that it not be a formal part of the function signature, that is just the = implicit status quo. This is likely something this RFC or a precursor = RFC should ask voters to vote on explicitly, and then it would be = decided. --Apple-Mail=_8CA716FA-2DDB-48BF-B2B0-807F4E32A1D3 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
On = Aug 26, 2024, at 8:28 AM, Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:

On = Mon, 26 Aug 2024, at 11:43, Mike Schinkel wrote:
You ask = how a library can provide access to that default, and the answer is = generally pretty trivial: define a public constant, and refer to it in = the parameter definition.

A = global? Really?

I didn't say = "global", I said "public".

I was imprecise in my description. I meant = "global" in the general programming sense and not in the PHP keyword = `global` sense.

Sorry about my lack = of precision here.

Since you're keen on = real-world examples, here's a simplified version of a real class:

class ConfigSource
{
= private HttpClientInterface $httpClient;

= public const DEFAULT_CONSUL_URL =3D 'http://localhost:8500';

public function = __construct(private string $consulUrl=3Dself::DEFAULT_CONSUL_URL, = ?HttpClientInterface $httpClient=3Dnull)
{
= = if ( $httpClient =3D=3D=3D null ) {
= $httpClient =3D new HttpClient();
= $httpClient->setRequestTimeoutSecs(5);
= $httpClient->setConnectRequestTimeoutSecs(5);
= = }
$this->httpClient =3D = $httpClient;
}
}
This constructor has two optional parameters; one of them = uses a default which is also referenced explicitly in another class, so = is exposed as a constant; the other uses a completely opaque method of = creating a default object, which even Reflection could not expose.

The caller doesn't need to know how any of = this works to make use of the class. The contract is = "__construct(optional string $consulUrl, optional ?HttpClientInterface = $httpClient)"

The purpose of the optional = parameters is so that you can write "$configSource =3D new = ConfigSource();" and trust the library to provide you a sensible default = behaviour.

Thank you (sincerely) for taking the time to author a = real-world use-case.

If it was decided that the code for creating a default = HttpClient was needed elsewhere, it could be refactored into a method, = with appropriate access:

public function = __construct(private string $consulUrl=3Dself::DEFAULT_CONSUL_URL, = ?HttpClientInterface $httpClient=3Dnull)
{
= $this->httpClient =3D $httpClient ?? = $this->getDefaultHttpClient();
}

public function getDefaultHttpClient(): HttpClient
{
$httpClient =3D new = HttpClient();
= $httpClient->setRequestTimeoutSecs(5);
= $httpClient->setConnectRequestTimeoutSecs(5);
= return $httpClient;
}

So, nullable is an = equivalent to the union-type concern my discussion with John Coggeshall = uncovered, correct? 

When two different types can be passed then we cannot depend = on the `default` being a specific type.

Or perhaps the HttpClient becomes nullable internally:

public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, private ?HttpClientInterface = $httpClient=3Dnull) {}

Or maybe we allow = explicit nulls, but default to a simple class instantiation:

public function __construct(private string = $consulUrl=3Dself::DEFAULT_CONSUL_URL, private ?HttpClientInterface = $httpClient=3Dnew HttpClient) {}

None of = these are, currently, breaking changes - the contract remains = "__construct(optional string $consulUrl, optional ?HttpClientInterface = $httpClient)".

Great example.

Now consider the following, assuming the RFC = passed but with an added requirement that `match()` be used exhaustively = for nullable parameters (shown) or parameters type hinted with unions = (not shown):

$configSource =3D new = ConfigSource(default,match(default){ 
= NULL=3D>new = ConfigSource->getDefaultHttpClient()->withRequestTimeoutSecs(5),
= default=3D>default->withRequestTimeoutSecs(5)
})

Ignoring that this expression is = overly complex, if covering all "types"  would be a = requirement in the RFC =E2=80=94 where `NULL` is a type here for = purposes of this analysis =E2=80=94can you identify another breaking = change if the RFC passed?

On Aug 26, 2024, at 8:43 AM, Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:
On = Mon, 26 Aug 2024, at 11:43, Mike Schinkel wrote:
But saying that we can be certain default values are private = and we 
want to keep them that way is provably false = by the existence of 
Reflection.  
Right now, accessing the default value of an = optional parameter is in the "possible if you mess around with = Reflection APIs" set; maybe we do want to move it to the "is part of the = language" set, maybe we don't; but claiming there is no distinction is = nonsense.

Now don't go putting words in my mouth, Rowan. ;-)

I did not say there was = _no_ distinction, I said that we cannot be *certain* the values are = indeed private. Subtle difference I admit, but there _is_ a difference. = :-)

On = Aug 26, 2024, at 12:59 PM, Larry Garfield <larry@garfieldtech.com> wrote:
The = problem here is that `foo(default | ADDITIONAL_FLAG)` is so far the most = compelling use case I've seen for this feature.  It's really one of = only two I see myself possibly using, frankly...

The other compelling case would be the rare occasions where = today you'd do something like this:
<snip>
foo($beep, $user_provided_value ?: default);

Is = `foo((default)->WithLogger(new Logger));` not a compelling use-case = =E2=80=94 which illustrates the clone of an default initialized object = with injected dependencies with one or a few properties then modified = =E2=80=94 or did you just miss that use-case in the volume of this = thread?

On Aug 26, 2024, at 1:35 PM, = John Coggeshall <john@coggeshall.org> wrote:
=46rom = the example you gave it appears that we can have a concrete problem = when:
1. There is a parameter with a default = value,
2. That parameter is type-hinted,
3. The hinted type is declared as a union type,
4. An earlier version of the library initialized the default = with a value having one of the union types,
5. = End-user developers used the library and then use `default` as an = expression of that type, and finally
6. The library = developer changed the initialization of the `default` to a different = type from the union.
Did I correctly identify the = problematic use-case?
Not really. #2 and #3 are irrelevant mixed  is actually much more problematic, I = wanted to provide an example that was strongly typed intentionally to = show the problem even when types were explicit. The relevant portion is = #1,  #5 and #6.

For the purpose of this analysis `mixed` can be = considered just a special case of a union-type where the types available = are "all."

You say #2 and #3 are = irrelevant and mention `mixed`, but if we consider `mixed` as a special = type of union then #2 and #3 become relevant again (as well as nullable, = as Rowan uncovered, which is itself a special type of = union.)

Or maybe there are problems = with single types that we have not uncovered yet?
Ok, so = for argument sake, what if they revise the RFC to only allow `default` = to be used in an expression when the parameter is not type-hinted with a = union? Would that address your concern? Or are there other use-cases = that are problematic that do not hinge on the parameter being = type-hinted as a union type?

It= wouldn't be enough, offhand it'd also have to be forbidden = for mixed  

Okay =E2=80=94 with the comment below = considered =E2=80=94 then assuming the RFC were to disallow using = `default` as an expression when the parameter were type-hinted with = `mixed` (and when no type hint is used), what are breaking changes we = still need to worry about?  

Note `default` could still be used with = `mixed`, but only by itself, not in an expression.

(at which point I think the = utility isn't there anymore).

I think this argument is provably false = by the fact that =E2=80=94 minimally =E2=80=94 the use-case that has = resonated with several people who are otherwise lukewarm has been = bitmapped flags, for which type hinting as `mixed` would be an obvious = code smell.

But = even so, it is up to the RFC author to decide if those limitations would = diminish the utility too much to continue the RFC, and then for the = voters to decide if they agreed with the remaining utility.

On Aug 26, 2024, at 2:11 PM, Matthew Weier O'Phinney <mweierophinney@gmail.com> wrote:
There's been a few good lists about the cool things this = could enable, demonstrating the value; maybe now we should focus on the = "we absolutely shouldn't enable" pieces to allow for broader = consensus. 

+1!

On Aug 26, 2024, at 2:49 PM, John Coggeshall <john@coggeshall.org>= wrote:
Perhaps the answer could be = to only allow the use of default  when = the assigned default value is a scalar value -- no objects, arrays, = enums, etc (and no mixed ).. 

FWIW, that would eliminate many of the use-cases = for me where I see the feature has value. 

On Aug 26, 2024, at 3:12 PM, Bilge <bilge@scriptfusion.com> wrote:

Whilst this is a curiosity, consider that = passing match expressions directly to arguments is something I = personally have never witnessed and that goes doubly for combining it = with `default`. So, whilst it is interesting to know, and important for = the RFC to state the specific semantics of this scenario, the practical = applications are presumed slim to none

Eh, = see nullable and union types (mentioned above.)  :-)

-Mike

P.S. The more I think about this, the = more I think that the default value *should* be a formal part of the = function signature. The fact that has not been explicitly defined before = now =E2=80=94 due to the fact it wasn't relevant before this RFC =E2=80=94= does not automatically require that it not be a formal part of the = function signature, that is just the implicit status quo. This is likely = something this RFC or a precursor RFC should ask voters to vote on = explicitly, and then it would be decided.

= --Apple-Mail=_8CA716FA-2DDB-48BF-B2B0-807F4E32A1D3--