Merging some replies together here... On Sun, Mar 22, 2020, at 8:36 PM, Levi Morrison via internals wrote: > > In short: I believe our biggest potential win is to focus on 3 RFCs: > > > > * Constructor Promotion > I would vote yes on this, assuming the implementation is sane.
On Mon, Mar 23, 2020, at 12:55 AM, Michał Brzuchalski wrote: > That still doesn't resolve issue with lot of boilerplate when you deal with > small objects for which public readonly is enough like object-initializer > could. So I'm not sure about my vote here. It does solve only one narrow > situation for me. The value here is combining constructor promotion with named parameters. Constructor promotion itself is useful for the class implementer, but doesn't help the caller. Named parameters helps the caller, but doesn't really help the class implementer. The combination of both of them together gives us something similar to the object-initializer syntax as a net result, but with many other benefits because it's not a one-off syntax. So with the two of them together, you get: class Point { public function __construct({public int $x, public int $y}); } Which then allows any of these construction mechanisms: $p1 = new Point(5, 7); $p2 = new Point({x: 5, y: 7}); $p3 = new Point({y: 7, x: 5}); All of which result in an object you can use the same way: print $p1->x . ', '. $p1->y; > > * Named parameters > This one is tricky -- there are tradeoffs of every approach I've seen > proposed. I have an idea for another way to address this space, but it > too has drawbacks; there's inherently no free lunch here, I think. Please share. I make no claim of being fully versed in the implementation details of how these would work at the engine level, only at the syntax level. > > * Compound Property Visibility > What is this last one? I searched for "compound" in the article, but > did not get many hits, none of which described what it actually _is_. Mm, yeah, I sorta changed names on that part way through. That's the "different visibility for read and for write" proposal that Nicolas mentioned in the readonly thread, for which I borrowed the syntax from the property accessors RFC. On Mon, Mar 23, 2020, at 1:07 AM, Mike Schinkel wrote: > 1. Your post mentions validation needed for value objects — a concern I > share — but AFAICT your conclusion does not address the issue. It doesn't directly in a syntactic way. Rather, it allows the constructor and Setter/Wither methods to still exist as now, and users can write what they want in there. That is, it's no change from now. That was one of my evaluation criteria: Improve as many of these as possible without making any of them worse.. This is one were "nothing is made worse". > 2. It also mentions overlapping concerns and references numerous RFCs, > but there were two other relative works not mentioned. One[1] is an RFC > and the other[2] a PR on Github. I think they both overlaps with this > problem space, with the former addressing validation whereas the latter > case potentially conflicts with constructor promotion. You are correct, I forgot about the impact of annotations (which I also support). Off hand, I think their only issue would be in relation to the constructor promotion, as the resulting syntax to put a bunch of annotations inside the constructor definition would get... silly. That suggest we may want a different syntax for constructor promotion than what I proposed we borrow from Hack, but I don't think changes the overall argument. > 1. You don't really address the value object vs. service object > distinction, except on the periphery. Correct. This also ties into your discussion of Structs/Records as an alternative approach. I have considered that before, but in this writeup... I found nowhere that any of the possible implementations would be useful only for one or the other. Rather, certain features may be more useful to one or the other but would definitely have uses in both. At the end of the day, I think the only language-level difference between a value and service object is the passing semantics; service objects should pass as they do now, while value objects would, ideally, pass in a way more similar to arrays. However, that was off topic at this time, and not needed. Everything else discussed would be applicable to both object types, so splitting the syntax would not be helpful, just confusing. For instance, property accessor methods on a new Struct type would have the exact same performance issue as they would on a Class today. The goal was to focus on the minimum amount of work we can do to get the maximum benefit, and I don't think a new Struct type would qualify for that. > 2. You mention the concerns about exposing parameter names as part of > the API but don't address those concerns directly. I do. Specifically, making named parameters opt-in allows class/function/method authors to decide if they want to make their parameter names part of the API or not. The alternative to support it on all callables period, which is also a viable option but, as noted in the writeup, technically a BC change. Either approach is possible. Now that I think about it, though, named parameters and variadics may not play nicely at all, so we may want to force it to be opt-in only (and incompatible with variadics). > 3. You mention get/set properties surprisingly running code but do not > address those concerns directly. That's only an issue with full property accessors, which I specifically do not propose we implement at this time. I was trying to represent the arguments against property accessors last time, as I remembered them; I personally don't think it's a problem and would love to have property accessors exactly as described in the RFC, if the performance issues could be resolved. Since that's not what is being proposed, determining if that's even an issue is not within scope. > 4. Your concept for a JSON object-like syntax for passing parameter > feels incomplete to me. Unless I miss understand it is just a special > syntax that only works in the context of passing arguments to a > constructor, method or function, and not a first-class language > element. If we were to go that route I think we would find it highly > limiting. The JSON-esque syntax was one of the options previously discussed the last time named parameters came up. I am not wedded to it, it was just the most readily-available way to demonstrate named params being opt-in. If we make them not opt-in, then there is no need for a special syntax at all. I was very specifically NOT trying to propose a Javascript-like Object Literal syntax. It's just one option among many for denoting a named parameters call. So, yes, it only works in the context of passing arguments, by design, that's the point. > 5. In the section you say that "either of the following construction > styles becomes possible" but you do not talk about the option of having > one of more of the first parameters being positional and the rest being > able to be passed by name, which I think would be an ideal use-case > when you want to force certain parameters to always be passed but make > the rest optional. Incorrect. I specifically say in one of the notes that we could consider it, but it's not necessary and may be more trouble than it's worth. It's more in-the-weeds than I wanted to get at this stage. Specifically: "We can consider mixing positional and named parameters the way Python does, but I don't think that's necessary." Regarding interaction with Delegation (a la Go, which I also agree is a very nice feature and we wants it, precious), I'm not sure. I would have to defer to Nikita for how that would interact with constructor promotion. Between that and annotations we may well want to explore a different syntax than Hack, but the essential concept is the same. > 2. Going further with constructor promotion, which you join with named > parameters, how are the parameters represented inside the > constructor/method/function? As different variables methods just like > current parameters? Is there no concept of automatic aggregation of > those parameters into some kind of structure that could then be passed > down to other methods and functions? Yes there is; it's called $this. The whole point of constructor promotion is that it avoids you writing $this->a = $a; $this->b = $b; $this->c = $c; One possible implementation in fact is to simply auto-generate those exact op codes in the source as it's getting parsed. If you want to then add additional logic in the constructor body that would run after those assignments, cool, those still work, and the corresponding properties are already populated for you to use if needed. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php