Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:101636 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 62340 invoked from network); 20 Jan 2018 06:09:11 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 20 Jan 2018 06:09:11 -0000 Authentication-Results: pb1.pair.com smtp.mail=andreas@dqxtech.net; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=andreas@dqxtech.net; sender-id=unknown Received-SPF: error (pb1.pair.com: domain dqxtech.net from 209.85.215.45 cause and error) X-PHP-List-Original-Sender: andreas@dqxtech.net X-Host-Fingerprint: 209.85.215.45 mail-lf0-f45.google.com Received: from [209.85.215.45] ([209.85.215.45:38432] helo=mail-lf0-f45.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D0/04-12394-40DD26A5 for ; Sat, 20 Jan 2018 01:09:10 -0500 Received: by mail-lf0-f45.google.com with SMTP id g72so4583340lfg.5 for ; Fri, 19 Jan 2018 22:09:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=aAXU7zq621bT5UkQK6Dstpfeb+9mJEqzhqBHzGmftYU=; b=Ss2S4GmGLkUU/Rq77Y7krvU7vmnwblUu+dXCOa9bn5TjqNvoUpltaVNlE+h1af3nlq 07ZcqOvFc8aYezmLSYJLBWMsQ3BgZn/QKXEWWdWxy+5yeWLEzLQ47w0fJJJkFFtzHWT0 Pd0AIS9tYe5q6E6fLhwyuJNA5NVctOfqLFv1zttEs3UlIK2RptczAPNdjGg2/2in/xeg kZxBSR709DvuizDtFZcAhdNeuHotT6MKpI2DT/AEbjeebkd+DPtU6B58O6fnHZe6zbMs q4IQZPNYl3XLwlAyhS/MJLIPqZN22vFiXxFdwr12e8Z0u0jdg9HWXpVOH77QTw1i8DHP bVwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=aAXU7zq621bT5UkQK6Dstpfeb+9mJEqzhqBHzGmftYU=; b=SQmTkY7QZuG7lPjj0Mwu+66X9PzJrPoo/O4v/qX8qgJATNFMcHQfLzJ99obbrKfyol 6Sxlze6ZlPpZBIjXvrBWavhT8LUr61qsa1P1+O9i2J2FoqtssYYIAwQxZ9OCKJGpQ5Io KUCepkKV8+VUW9xJbTwcf1/gw9ZEOhYU80QhmgJ1J5mwOZLz3TTG7DalnwMkeYM1LAjf xAtzklqSoWOq57OYQ4YC71AKBXL85sLfmIX3A5G8LYNBYhKivMi20YzQEuWa4LaXLJQ0 yaRB7ZrJYIEaHQ7utxBHtLg5tlZM91phsFdGffaUShWGvyWWYXV4o4iUR2w69j+0qUGi uZXw== X-Gm-Message-State: AKwxyte2Zsx3ff4FrRtY5Eb/SiocfVaomDt17P4KMck9aRoQO36mR/64 14/svT7aN5UoOLG66oIju7VnNrWI X-Google-Smtp-Source: AH8x224p0EUdBpRw0ZroaGyKFboAngzFDNc35NN8ac+sVf5wuLNTOxnUTeyI8LSoVyLPrPuf7B+efQ== X-Received: by 10.46.47.25 with SMTP id v25mr368827ljv.15.1516428545274; Fri, 19 Jan 2018 22:09:05 -0800 (PST) Received: from mail-lf0-f46.google.com (mail-lf0-f46.google.com. [209.85.215.46]) by smtp.googlemail.com with ESMTPSA id j9sm549262lfe.43.2018.01.19.22.09.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 19 Jan 2018 22:09:04 -0800 (PST) Received: by mail-lf0-f46.google.com with SMTP id t139so4587770lff.0 for ; Fri, 19 Jan 2018 22:09:04 -0800 (PST) X-Received: by 10.46.85.66 with SMTP id j63mr465384ljb.55.1516428543899; Fri, 19 Jan 2018 22:09:03 -0800 (PST) MIME-Version: 1.0 Received: by 10.25.163.71 with HTTP; Fri, 19 Jan 2018 22:08:43 -0800 (PST) In-Reply-To: References: <9a4e54d1-10d8-889e-e705-fe473e2e3713@gmail.com> <3aa2372c-c31a-d41a-f455-35ce400b382b@gmx.de> Date: Sat, 20 Jan 2018 07:08:43 +0100 X-Gmail-Original-Message-ID: Message-ID: To: Aidan Woods Cc: Sara Golemon , "Christoph M. Becker" , Stanislav Malyshev , PHP internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] null coalesce addition assignment operator ??+= From: andreas@dqxtech.net (Andreas Hennings) As mentioned earlier: In hack (hhvm), operators like +=, *= etc do allow the left side to be undefined. (However, ++ and -- do not allow the left side to be undefined.) I wonder if this is intended, or by accident. On 20 January 2018 at 06:47, Andreas Hennings wrote: > On 20 January 2018 at 04:29, Aidan Woods wrote: >> On 20 January 2018 at 01:25, Andreas Hennings wrote: >>> >>> On 19 January 2018 at 16:12, Sara Golemon wrote: >>> > On Thu, Jan 18, 2018 at 7:13 PM, Christoph M. Becker >>> > wrote: >>> >> On 18.01.2018 at 23:58, Stanislav Malyshev wrote: >>> >> >>> >>>> I propose even more such operators: >>> >>>> null coalesce addition assignment ??+= (for strings and numbers) >>> >>>> null coalesce subtraction assignment ??-= >>> >>>> null coalesce increment ??++ >>> >>>> null coalesce decrement ??-- >>> >>>> null coalesce multiplication assingment ??*= >>> >>> >>> >>> I think this is taking it too far. If you want language like that, you >>> >>> always have APL :) >>> >> >>> >> Why do we discuss extensions to an operator which has still (after >>> >> nearly two years) not be implemented due to implementation >>> >> difficulties? >>> >> >>> > Am I the only one who looked at the original post and assumed he was >>> > taking the piss? >>> > Similar to the jokes about spaceship assignment <=>= and >>> > equality/identicality assignment === (not to be confused with >>> > identical non-assign, which is ===) and ====. >>> >>> I can definitely say it was not a joke. >>> I can see myself and others use the ??+= and also ??++, and would have >>> used them in the past, if they had been available. >>> The others, I don't care as much. >>> >>> For me, a good enough conclusion of this conversation would be one of: >>> A: Yeah seems useful, but let's wait (or work) until ??= is >>> implemented and released, and observe how it is being used. >>> B: No one will ever use it, and it would hurt the language. >>> >> >> Going by the example, would this operator's behaviour be a little confusing? >> >> As I understand it the (maybe) upcoming `??=` operator will assign in the >> case that the lhs is *not defined*. >> But for `??+=` incrementing appears to be desired when the lhs *is defined*, >> (with assignment to the operator related identity element in the case that >> the lhs is undefined). >> >> While the use-case seems to add value in the scenario, I think it is >> possibly >> inconsistent with the way `??=` works? > > I think it depends how you see it. > > // shortcut > return $x ??= 5; > return $y ??+= 5; > > // spelled out, looks inconsistent > return isset($x) ? $x : ($x = 5); > return isset($y) ? ($y += 5) : ($y = 5); > > // spelled out, looks a bit more consistent (despite being broken) > return (isset($x) ? $x : ($x = 5)); > return (isset($y) ? $y : ($y = 0)) += 5; // invalid code, because > ternary is not a valid lhs. > > The line is invalid, but shows the mental model or the excuse that > allows us to claim this is consistent. > > But yeah, I can see how someone would expect a different behavior: > > return isset($x) ? $x : ($x = 5); > return isset($y) ? $y : ($y += 5); > > This would not make sense or be useful because: > For $y === NULL, this would evaluate as > return $y = NULL + 5: > > Still, your argument raises a valid concern that the operator might be > misunderstood. > > > > If we get ??=, I previously thought we could use it like this, to > replicate ??+=: > > return ($y ??= 0) += 5; > > Unfortunately, I think we can expect that ??= won't be a valid lhs, > because neither is *= or += etc. > E.g. this is invalid: > ($y *= 3) += 1; > https://3v4l.org/oKIkl > > >> >> Furthermore, I think you can generalise this in user-land and end up with a >> better result. > > comments below. > >> >> When dealing with structured data (i.e. when you expect strings mapping to >> ints in your example) you may consider writing a simple class for making >> such type guarantees. Something simple like https://3v4l.org/5Sh04 would >> produce the desired result, and let you obtain the result in one line at >> point >> of use. >> >> Nothing ties you into using a class for the storage though, you could >> simplify >> even further and just create some abstract class representing an "array >> toolbox" >> for these kind of operations, e.g. https://3v4l.org/ZJcom >> So that the array initialisation, foreach loop, and operator are replaced >> with a >> single line again at point of use (after defining the arraytools class >> once). >> >> If you wanted it to work more generally, you could use a reference to delay >> lookup, and keep your current code structure https://3v4l.org/TJYhq > > I was never a big friend of those array functions with callback > arguments, which force me to remember a signature. > I find a simple foreach() to be more readable. I think it is also faster. > > So yeah, I prefer this example to the previous ones. > >> >> If you wanted it to look the part you could even sneak some unicode symbols >> in to make it look like some sort of operator ;-) https://3v4l.org/MVT85 > > Looks interesting, but people have to type this! So, no unicode symbols. > >> >> Kind regards, >> Aidan > > If I were to do it in userland, it would either be > - in my own custom library or application, where it would not be used > by others, or > - in a shared package, which other packages could add as a dependency. > > I think usually people will decide against adding a dependency for a > bit of syntax sugar. > E.g. if the existing null coalesce operator was provided as a userland > solution, I don't think this package would have become popular. > Instead, code that uses such a package would become less readable, not > more readable. > > I remember when I was dealing with CiviCRM, which had those "something > smart with arrays" functions. > Maybe they had the same purpose as what we discuss here, or they did > something else. > The result was: Whenever I had to look at such a call, I was confused, > and had to re-confirm what it does. > Maybe it could have gotten used to it, but I did not spend that much > time with CiviCRM. > > Nowadays I prefer native features, even if they are more verbose. > They also need to be learned / gotten used to, but at least this > experience will be the same for everyone. > > I also often do these kinds of array-crunching operations in throwaway > code for debugging, e.g. to build a statistic for a bunch of values. > In such cases I don't want to add a new dependency to the application.