Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125487 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 7EBBA1A00BD for <internals@lists.php.net>; Tue, 10 Sep 2024 08:01:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1725955387; bh=jEOIHawxP/ZjjXpEecXGHQjVE6REmLbhyJfH00BSzeA=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=M7yCowAJ4v2/TnhYig/fxteVs+78mCFPY3Rvm7+DEGD0fjcSzJKzMz1H03HjH59l8 PIgXmIW651tf37tDP/xSQJ1OGNrVH9BGcOr53pv2L0v6/V0Hd6vEZSzEVocq+538pH pRd0JXOirhK8MfP2d0gVxgbR9c12WuwCcu9j4ZVmohBRTBdVkLxqRPtxvnOkhVkZ/7 8g+n10NJd6Ki/oER+llZmigT00tR3/F30w4Y0urrPspCgioJgYzNBmfUN/I0Bq524Z 2ECTKAJo6ZVxo9yarjjl8IM8jaglnbB+SwasmFh6C27PS1+lx03cMbYj1Q1RaLbqKY yvYqdWIf/de4A== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 796FA180076 for <internals@lists.php.net>; Tue, 10 Sep 2024 08:03:02 +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_MSPIKE_H2,SPF_HELO_NONE, SPF_NONE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: <mike@newclarity.net> Received: from mail-yw1-f169.google.com (mail-yw1-f169.google.com [209.85.128.169]) (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 <internals@lists.php.net>; Tue, 10 Sep 2024 08:03:01 +0000 (UTC) Received: by mail-yw1-f169.google.com with SMTP id 00721157ae682-6c3f1939d12so46003127b3.2 for <internals@lists.php.net>; Tue, 10 Sep 2024 01:01:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1725955260; x=1726560060; 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=3t8q2FO7CY5dV1uqZc0Cu16RWTI7jBXOelCC8OaHJk8=; b=zkfu5jO1ru/IZna8YKAEGY9qD4gUBw7IfXxMe1oyrjQPjGvR4zkN6VknPPJs4RZFAi vuOTZmyjJAJewphMPCKYjGu8PLeEvjIE7gpbN2xIennsrwX27LS4EeRMeFy1N3vVaPnR I+m6EJrc4QiSlgR6ftCKw25LZ0vZS3BMcZGJpcrjWOwzv2qUI3c2QAm1w3uEQ/tF2yT/ L+19OQuCjA0WZA6iDn1iNMy+usnHZF4dH8Soajo4qqb4xXgVqx8BlswigR15GkGC6Iga 1yFKOP6TylMyyk4fugEGoGTs1tIHfZuiVYsbJHk8NJazznwnlrFQXxOlUBNJagivnFTU EDPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725955260; x=1726560060; 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=3t8q2FO7CY5dV1uqZc0Cu16RWTI7jBXOelCC8OaHJk8=; b=Q2jOhwRtbCoeQZIfWcfMslk9Ouk9lEaEx5F+48lwzUCEtBWkD2PffmQOBVTLzcvtzC QicJWI716vWOWsouaOaRItK+qDk+pMszj17s+OtB0I7MtROQnzdYA+rPZKPlirNh0+my Kvt6aJ56qZhLlqKfLOO+0RJOaYXDeH5T59o/FKlL3xLdoSVU67lQET3uLQT7jCX72W5g 2WprPF5QPCxYrKOg+MaUzprA6r0tgtaSKiOPEFfxwWx//cL673IHGstPm9S4hP5DAk+k Xw5r0kFwAufamYXHYPaZ+631KmWX/muo2sA+LOTRoikSvSZoxcRrp0Y0I3gpZNRRLZPB 488w== X-Gm-Message-State: AOJu0Yz+8sCfx/fP5hA5yyQsYyAEQ0CZmz6l+CQt3Q6Jbyp5P6lR3R51 4siEO0ZQNJ9PUzv6+yeF12MeP/Bv0pchcOJrHunAUxvsJ3y7BgJoZ61cqnxqDuoliDiIOPzy4ei IsTQ= X-Google-Smtp-Source: AGHT+IGQXc0o4azc8pvQEG6Cyg3XrvIxHKJebRJBleQosZdaVjxvpkFw8/PJNVflvpCG4gZfxpFrAg== X-Received: by 2002:a05:690c:4604:b0:6ae:2f25:8bc4 with SMTP id 00721157ae682-6db44f2c242mr117316887b3.16.1725955260100; Tue, 10 Sep 2024 01:01:00 -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 00721157ae682-6db96486f1csm2201157b3.58.2024.09.10.01.00.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Sep 2024 01:00:58 -0700 (PDT) Message-ID: <50CFF539-AD22-4F89-A65E-77AF76DBD63A@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_4DA80B8B-01DD-4204-BCD4-BDABBD30AC7D" Precedence: bulk list-help: <mailto:internals+help@lists.php.net list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net> list-post: <mailto:internals@lists.php.net> 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] bikeshed: Typed Aliases Date: Tue, 10 Sep 2024 04:00:56 -0400 In-Reply-To: <212fd466-85bc-4447-90b7-8fe5426d1bd1@rwec.co.uk> Cc: internals@lists.php.net To: "Rowan Tommins [IMSoP]" <imsop.php@rwec.co.uk> References: <0fa39535-f22d-4eba-b4df-90abe39e683a@app.fastmail.com> <e73be2b0-faa9-42eb-a9f6-8308cf4f8c94@app.fastmail.com> <ed3847bf-af2e-4e33-ac09-66e44696fdeb@app.fastmail.com> <79e58673-50ec-461e-a998-736b020e4287@app.fastmail.com> <a3cd6d90-cfac-40d5-a59a-c9f6d9dbe5f0@app.fastmail.com> <928A2984-6035-4DA6-9EA7-12E85237C270@php.net> <0d461700-1b6c-44fd-9cda-aa698de49847@app.fastmail.com> <667233C2-BC47-4530-8142-D90E6907FE63@daveyshafik.com> <D95D21CE-45AB-487A-B59D-40305C0C569D@rwec.co.uk> <63d241a8-a34a-498c-a5f9-f34230aa5afa@app.fastmail.com> <4C7A7F27-B787-44CA-B664-CEF4B9B412FB@newclarity.net> <212fd466-85bc-4447-90b7-8fe5426d1bd1@rwec.co.uk> X-Mailer: Apple Mail (2.3696.120.41.1.10) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_4DA80B8B-01DD-4204-BCD4-BDABBD30AC7D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Sep 9, 2024, at 5:35 PM, Rowan Tommins [IMSoP] = <imsop.php@rwec.co.uk> wrote: >=20 > On 09/09/2024 19:41, Mike Schinkel wrote: >> In Go you cannot add or subtract on a typedef without casting to the=20= >> underlying type. I would definitely prefer that to be relaxed, but = only >> if it is relaxed via an explicit opt-in, e.g. something maybe like=20= >> this: >>=20 >> typedef UserId: int operations: +, -, *, /; >> typedef UserName: string operations: .; > I think this would stray into some of the same complexity as operator = overloads on objects, in terms of the types and values allowed. For = instance: >=20 I tend to agree that allowing operations may be too much for an initial = scope given that it is unlike anything else in the current language and = with no other languages offering an equivalent AFAIK. I would however make the distinction that it is unlike operator = overloading because the big concern was what constituted an operation = for any given type could be too subjective. In your example of `Metres` = it is pretty obvious, but not at all obvious for a `User`, for example. = (BTW, thank you for not calling out my nonsensical example of operations = on a `UserId`; when I wrote that I clear was not thinking about if they = were relevant, doh!) However give the suggestion regarding operations with a typedef, the = only operations that I suggested would be valid would be the ones = already defined on the underlying type, (when I mentioned other = operations I was thinking of methods =E2=80=94 see my the following = example with round =E2=80=94 not operators so that is not the same as = operator overload.) For example: /** * Currency is an int so for example in USD 1=20 * unit of currency not a dollar but a cent. */ typedef Currency: int operations: +,-,*,/,round; function CalcTotal(Currency $subTotal, Currency $shipping, float = $tax):Currency { return round($subTotal*(1+$tax/100),0) + $shipping; } > typedef Metres: int; >=20 > assert( Metres(2) + Metres(1) =3D=3D=3D Metres(3) ); // most obvious > assert( Metres(2) + 1 =3D=3D=3D Metres(3) ); // seems pretty clear Both of those are in line with what I was suggesting. > $_GET['input'] =3D '1'; > assert( Metres(2) + $_GET['input'] =3D=3D=3D Metres(3) ); // might be = more controversial >=20 I would not consider this appropriate as it has two levels of conversion = and could thus end up with unintended edge cases. To do the above I = think you would have to either convert or typecast: assert( Metres(2) + intval($_GET['input']) =3D=3D=3D Metres(3) );=20 assert( Metres(2) + (int)$_GET['input'] =3D=3D=3D Metres(3) );=20 > typedef Feet: int; > assert( Metres(2) + Feet(1) =3D=3D=3D Metres(3) ); // almost certainly = a bad idea >=20 This would be operator overloading where knowledge of the conversion = between meters and feet would be required, and that is not in any way in = scope with what I was suggesting. =20 As an aside, I am against userland operator overloading as I have seen = in other languages that operator overloading gets abused and results in = code that is a nightmare to maintain. OTOH, I would support operator = overloading in specific cases, e.g. a `Measurement` class in PHP core = could allow adding meters to feet, assuming such a proposal were made = and all other aspects of the RFC were of the nature to be voted in. To reiterate on typedefs, what I was suggesting was that if an operation = was explicitly allowed =E2=80=94 e.g. + =E2=80=94 then anything that = would work with the underlying type =E2=80=94 such as adding an int 1 = would work without typecasting and yet still result in the typedef type, = e.g. Meters(2) + 1 results in a value of type Meters. (note that I = corrected your spelling of 'Meters' here. ;-)=20 But I agree, this is probably a bridge too far for a first RFC for = typedefs.=20 >> type MyNewType: Foo >> type MyAlias =3D Foo > I know this was only an example, but as a general point, I think we = should avoid concise but cryptic differences like this. PHP is generally = keyword-heavy, rather than punctuation-heavy, and I think that's a valid = style which we should keep to. Here, I also tend to agree WRT PHP. Was just pointing out for sake of = laying out other options that were implied not to exist. -Mike --Apple-Mail=_4DA80B8B-01DD-4204-BCD4-BDABBD30AC7D Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 <html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; = charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; line-break: after-white-space;" = class=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On = Sep 9, 2024, at 5:35 PM, Rowan Tommins [IMSoP] <<a = href=3D"mailto:imsop.php@rwec.co.uk" = class=3D"">imsop.php@rwec.co.uk</a>> wrote:</div><br = class=3D"Apple-interchange-newline"><div class=3D""> =20 <meta http-equiv=3D"Content-Type" content=3D"text/html; = charset=3DUTF-8" class=3D""> =20 <div class=3D""> <div class=3D"moz-cite-prefix">On 09/09/2024 19:41, Mike Schinkel wrote:</div> <blockquote type=3D"cite" = cite=3D"mid:4C7A7F27-B787-44CA-B664-CEF4B9B412FB@newclarity.net" = class=3D""><pre class=3D"">In Go you cannot add or subtract on a typedef = without casting to the=20 underlying type. I would definitely prefer that to be relaxed, but only if it is relaxed via an explicit opt-in, e.g. something maybe like=20 this: typedef UserId: int operations: +, -, *, /; typedef UserName: string operations: .;</pre></blockquote><p class=3D"">I = think this would stray into some of the same complexity as operator overloads on objects, in terms of the types and values allowed. For instance:<br = class=3D""></p></div></div></blockquote><div>I tend to agree that = allowing operations may be too much for an initial scope given that it = is unlike anything else in the current language and with no other = languages offering an equivalent AFAIK.</div><div><br = class=3D""></div><div>I would however make the distinction that it is = unlike operator overloading because the big concern was what constituted = an operation for any given type could be too subjective. In your = example of `Metres` it is pretty obvious, but not at all obvious for a = `User`, for example. (BTW, thank you for not calling out my = nonsensical example of operations on a `UserId`; when I wrote that I = clear was not thinking about if they were relevant, doh!)</div><div><br = class=3D""></div><div>However give the suggestion regarding operations = with a typedef, the only operations that I suggested would be valid = would be the ones already defined on the underlying type, (when I = mentioned other operations I was thinking of methods =E2=80=94 see my = the following example with round =E2=80=94 not operators so that is not = the same as operator overload.) For example:</div><div><br = class=3D""></div><div class=3D""><div class=3D""><font color=3D"#000000" = class=3D""><span style=3D"caret-color: rgb(0, 0, 0);" class=3D"">/**<br = class=3D""> * Currency is an int so for example in USD 1 <br = class=3D""> * unit of currency not a dollar but a cent.<br = class=3D""> */<br = class=3D"">typedef Currency: int operations: = +,-,*,/,round;<br = class=3D"">function CalcTotal(Currency $subTotal, Currency&= nbsp;$shipping, float $tax):Currency {<br class=3D""> = return round($subTotal*(1+$tax/100),0) + $shipping;<br = class=3D"">}<br class=3D""></span></font></div></div><blockquote = type=3D"cite" class=3D""><div class=3D""><div class=3D""><p = class=3D"">typedef Metres: int;<br class=3D""> </p> assert( Metres(2) + Metres(1) =3D=3D=3D Metres(3) ); // most = obvious<br class=3D""> assert( Metres(2) + 1 =3D=3D=3D Metres(3) ); // seems pretty = clear<br class=3D""></div></div></blockquote><div><br = class=3D""></div>Both of those are in line with what I was = suggesting.<br class=3D""><blockquote type=3D"cite" class=3D""><div = class=3D""><div class=3D""><p class=3D"">$_GET['input'] =3D '1';<br = class=3D""> assert( Metres(2) + $_GET['input'] =3D=3D=3D Metres(3) ); // might = be more controversial</p></div></div></blockquote>I would not = consider this appropriate as it has two levels of conversion and could = thus end up with unintended edge cases. To do the above I think you = would have to either convert or typecast:</div><div><br = class=3D""></div><div>assert( Metres(2) + intval($_GET['input']) =3D=3D=3D= Metres(3) ); </div><div>assert( Metres(2) + (int)$_GET['input'] = =3D=3D=3D Metres(3) ); </div><div><blockquote type=3D"cite" = class=3D""><div class=3D""><div class=3D""><p class=3D"">typedef Feet: = int;<br class=3D""> assert( Metres(2) + Feet(1) =3D=3D=3D Metres(3) ); // almost = certainly a bad idea</p></div></div></blockquote>This would be operator = overloading where knowledge of the conversion between meters and feet = would be required, and that is not in any way in scope with what I was = suggesting. </div><div><br class=3D""></div><div>As an aside, I am = against userland operator overloading as I have seen in other languages = that operator overloading gets abused and results in code that is a = nightmare to maintain. OTOH, I would support operator overloading in = specific cases, e.g. a `Measurement` class in PHP core could allow = adding meters to feet, assuming such a proposal were made and all other = aspects of the RFC were of the nature to be voted in.</div><div><br = class=3D""></div><div>To reiterate on typedefs, what I was suggesting = was that if an operation was explicitly allowed =E2=80=94 e.g. + =E2=80=94= then anything that would work with the underlying type =E2=80=94 such = as adding an int 1 would work without typecasting and yet still result = in the typedef type, e.g. Meters(2) + 1 results in a value of type = Meters. (note that I corrected your spelling of 'Meters' here. = ;-) </div><div><br class=3D""></div><div>But I agree, this is = probably a bridge too far for a first RFC for = typedefs. </div><div><br class=3D""><blockquote type=3D"cite" = class=3D""><div class=3D""><div class=3D""><blockquote type=3D"cite" = class=3D""><pre class=3D"moz-quote-pre" wrap=3D"">type MyNewType: Foo type MyAlias =3D Foo</pre> </blockquote> <p class=3D"">I know this was only an example, but as a general = point, I think we should avoid concise but cryptic differences like this. PHP is generally keyword-heavy, rather than punctuation-heavy, and I think that's a valid style which we should keep to.<br class=3D""> </p></div></div></blockquote>Here, I also tend to agree WRT PHP. = Was just pointing out for sake of laying out other options that = were implied not to exist.</div><div><br = class=3D""></div><div>-Mike</div><br class=3D""></body></html>= --Apple-Mail=_4DA80B8B-01DD-4204-BCD4-BDABBD30AC7D--