Hi, Rob!

I'm just wondering, why the implementation differs from a regular class? 

Record makes a "class" immutable and unique, using field value comparison 
instead of object refs. It has a custom `with` method which is similar to the 
new `clone` operator accepted recently. I'd suggest not introducing a new 
keyword "record" and new syntax to create records, but use regular `class` and 
`new Class`. Class should have a modifier "data" like readonly, so it should be:

data class Record {
    public function __construct(public $a){} // $a is mutable, because why not?
}

Data class will compare with others using field value comparison. Moreover, if 
you want to make it readonly, use the existing keyword to achieve this:

readonly data class Record {
    public function __construct(public $a){} // $a is immutable, because of 
"readonly" class modifier
}

1. So record Record {} becomes readonly data class Record {}
2. We introduce data classes, which are similar to records and are mutable by 
default
3. No new constructions to create the new type of classes, no adjustments for 
autoloading and other things internally
4. Eliminate with method, replace `with` method with the new `clone`
5. Inline constructor isn’t necessary and could be proposed separately. I’ve 
thought recently about this feature

WDYT?

(sorry for the duplicate in private mailbox)

----------

Best regards,
Dmitrii Derepko.
@xepozz

> On Nov 17, 2024, at 2:14 AM, Rob Landers <rob@bottled.codes> wrote:
> 
> Hello internals,
> 
> I'm ready as I'm going to be to introduce to you: "Records" 
> https://wiki.php.net/rfc/records!
> 
> Records allow for a lightweight syntax for defining value objects. These are 
> superior to read-only classes due to having value semantics and far less 
> boilerplate, for most things developers use read-only classes for. They are 
> almost as simple to use as arrays (and provide much of the same semantics), 
> but typed.
> 
> As an example, if you wanted to define a simple User record:
> 
> record User(string $emailAddress, int $databaseId);
> 
> Then using it is as simple as calling it like a function, with the & symbol:
> 
> $rob = &User("rob@bottled.codes <mailto:rob@bottled.codes>", 1);
> 
> Since it has value semantics, we can get another instance, and it is strongly 
> equal to another of the same parameters:
> 
> $otherRob = &User("rob@bottled.codes <mailto:rob@bottled.codes>", 1);
> assert($otherRob === $rob); // true
> 
> Records may also have methods (even hooks), use traits, and implement 
> interfaces:
> 
> record Vector3(float $x, float $y, $z) implements Vector {
>   use Vector;
>   public float magnitude {
>     get => return sqrt($this->x ** 2 + $this->y ** 2 + $this->z ** 2)
>   }
> }
> 
> Further, an automatic (but overridable) "with" method is generated for every 
> record. This allows you to get a new record similar to a given one, very 
> easily:
> 
> record Planet(string $name);
> 
> $earth = &Planet("earth");
> $mars = $earth->with(name: "mars");
> 
> The depth of records was an immense exploration of the PHP engine, language 
> design, and is hopefully quite powerful for the needs of everyday PHP and 
> niche libraries. I took care in every aspect and tried to cover every 
> possible case in the RFC, but I still probably missed some things. I plan on 
> having a full implementation done by the end of the year and open to a vote 
> by the end of January, but I'd like to open the discussion up here first. 
> Love it or hate it, I'd like to hear your thoughts.
> 
> — Rob

Reply via email to