Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106298 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 9140 invoked from network); 25 Jul 2019 17:54:27 -0000 Received: from unknown (HELO mail-lf1-f45.google.com) (209.85.167.45) by pb1.pair.com with SMTP; 25 Jul 2019 17:54:27 -0000 Received: by mail-lf1-f45.google.com with SMTP id c19so34795731lfm.10 for ; Thu, 25 Jul 2019 08:18:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=mFq0/u53Izu4lAe3KcLu9B3Uytab92qBlv4I2J7UT9I=; b=FmAgzKaGmCnYGObG7R7IhVTdp2frbG8aTMHRsu682vjlyP5YHuyhZguGobvGY4T5W9 8oxBHdPPZY8E6/+cyGyzgigIyRlglXAdwb+wf0pnscSZjBUb+sawDzsov8cqf2HiPhpX CpqxWEuyi5IHGC2aJZVFZ4mdfewFjKFX0HUM7aiNDEeHmySOOBZcX5xB/vkyNc8FWKNR LwmTvuNNIhOLMmCbl59IGxN+qnaeHaJa2O5e+jicNpBg2V9CjVb/VXZ13GjjU+aTYFev H4XeIqyJUzWt0uP52ZdM4yrROIkwrbF9Nu5MSMi+AYk2p0eO5+YnYQxSsLI3TTyoC6qz zTuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=mFq0/u53Izu4lAe3KcLu9B3Uytab92qBlv4I2J7UT9I=; b=fZciAb95sg65HhejguIEOms/hYbtX5Lrzgoz8KXwmf1pS7R+prp9UTyRI3/TsNjUuF j/1GXFanGRvc86Nu29rKMLPZMQaIQ8zgDW2Hcx7eMmkhche8aV3dInknu4HbY+g0PII9 BZYFSB0J7m8Z8Y19YMI1d6IHx1TUAYn7652gM8RAFotXCRU8Y8HJ0sREl5qwh7pwnwfs e/pffEe7Phk3DC2ypG0EFobDSd1sLVNC5C6PDLGdjxlRv4qL9jYl4B9+GMcjWguCt62g zTZ+DNbg6EIXmYYTMhQ5fbqGIPjcjQaFazMt9WRoaCTB3AgQK1ozWeChf8mWdvueP68J mmsA== X-Gm-Message-State: APjAAAX2nBUU6n00OtC5g2Q37PVrEl36Ewgvp1Mhq0JmmUezNiBPi9lo n8WjNwfvasXRkQ/nMTwAKcIkrfdXzGV1HFYDm58= X-Google-Smtp-Source: APXvYqws566sknRH1GWO5MapxFZ2A5Rt85QrU4TSX7cPe+Xaqg4on/JkQCaGX3v8UqZUANtT0Mv8SMVd07z1+YvXNn0= X-Received: by 2002:ac2:44b1:: with SMTP id c17mr30837041lfm.87.1564067887044; Thu, 25 Jul 2019 08:18:07 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 25 Jul 2019 17:17:50 +0200 Message-ID: To: Rowan Collins Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000cfe064058e82eebd" Subject: Re: [PHP-DEV] Re: [RFC] Explicit call-site send-by-ref syntax From: nikita.ppv@gmail.com (Nikita Popov) --000000000000cfe064058e82eebd Content-Type: text/plain; charset="UTF-8" On Thu, Jul 25, 2019 at 4:41 PM Rowan Collins wrote: > On Thu, 25 Jul 2019 at 14:48, Nikita Popov wrote: > > > > I think nowadays it is well known that by-reference passing is to be > > avoided and I don't see it particularly commonly in user code. > By-reference > > passing is mainly used when it is needed to interact with existing > > by-reference functions such as preg_match(). We can hardly switch these > > functions to use out/inout if we require the corresponding keyword on the > > call-site. > > > > > I guess the call-site syntax would still need to be opt-in for > compatibility reasons, but we could definitely mark the parameters as "out" > in internal functions, even if that was mainly a documentation / reflection > change. > > That would stop people having to write `$matches = []; preg_match($foo, > $bar, $matches);` to ensure that the output parameter is initialised. I > have been annoyed by that more often than I've encountered a function where > I wasn't sure if the parameter was by-reference or not. > Eww, please don't write code like that... This proposal (in conjunction with the option to make it required) would > > solve the main issues I have with the by-reference passing implementation > > > > > If this remains optional, I wouldn't have much appetite for using it, > because the benefit feels very slight. The fact that it wouldn't always be > mandatory makes the benefit even slighter, since you still couldn't look at > foo($bar) and know whether it was by-reference without also knowing what > declare options were in scope. > For a drive-by contribution to an open-source project? Maybe not. For anything that you want to work on seriously (say your own code or your employers code), you'll want to check the declares and then have guarantees on how the language behaves. It's somewhat off-topic, but as George mentioned in his email, this doesn't have to be an agglomeration of individual declares that are randomly flipped on and off: It could also be something like a "language level" (like editions in rust). To sick with the analogy of Rust editions, think of it as switching your project to PHP 2020 -- where passing by-reference requires a call-site annotation, use of dynamic properties throws, operators have stricter type requirements, etc... So if you see foo($x) in your code, that's definitely a by-value pass! > > the out/inout approach is a refinement over that, but I'm not convinced > > that it a worthwhile refinement relative to the language and engine > > complexity it will introduce. > > > > > Would it really be that complex? The only real difference between "out" and > "&" would be automatically setting the variable to null when it was passed > to the function. > That depends on how the feature is supposed to work. For me, the main point of having out/inout would be a move away from references, so this would require the implementation of an entirely new calling convention for out and inout parameters. I would expect that $z = foo($x, out $y) would translate (in terms of behavior, not actual implementation) to something like [$z, $y] = foo($x) and $z = foo($x, inout $y) to [$z, $y] = foo($x, $y) The behavior of type annotations should also change, "out T $x" should check that the value assigned to $x on function exist (or possibly on every write to the variable?) is T. "inout T $x" should check that $x is T on entry, and also on exit (or on every assignment). This would be a pretty non-trivial change. The technically hardest parts would be the changes to type-hint behavior (depending on semantic details) and making this work if call-site annotations are missing (very hard). I think we should only do this if the call-site annotations are required (still leaving the problem of old functions). Of course, that's just what I have in mind ... the alternative (and likely what you have in mind) is to make out/inout parameters basically normal by-reference parameters, with the only difference that inout uses an RW fetch instead of a W fetch and thus throws a notice if the referenced variable does not exist. That's certainly a possibility (and technically much simpler), but I also think that it squanders most of the potential behind out/inout parameters. Nikita --000000000000cfe064058e82eebd--