Crell / enum-comparison

A comparison of enumerations and similar features in different languages
82 stars 7 forks source link

Type coercion? #35

Closed iluuu1994 closed 3 years ago

iluuu1994 commented 3 years ago

Do we really need type coercion? Especially since the RFC currently only allows one-sided coercion (from objects to scalars) I'd be happier dropping it altogether.

Crell commented 3 years ago

When else besides cases() would the primitive be used then? Having a primitive that you can never actually leverage except in cases() doesn't seem all that useful. I guess then we'd need a dedicated value() method after all...

iluuu1994 commented 3 years ago

Well, you still need a way to explicitly get the value. We'd need that for strict types anyway. And I've just realized that behavior isn't even described. We'd need something like $foo->value() or possibly even just $foo->value.

iluuu1994 commented 3 years ago

@Crell So, what do you think? IMO ->value() is easy enough that having to think about coercion is not worth it, especially given that PHP seems to have been striving for more strict type safety lately.

Crell commented 3 years ago

My main concern is what is going to make life easiest for people round tripping enum data to the database. I'm comfortable with whatever they're comfortable with.

iluuu1994 commented 3 years ago

I think if we do want type coercion we need it both ways (convert strings/ints back to the enum). I have not investigated how easy this is. What could also cause some headaches is something like this:

enum Foo: int {
    case Bar = 42;
}

takesString(Foo::Bar); // Do we convert to int and then string? Type error?

I'm ready to investigate this for a few hours if you feel coercion is important.

Crell commented 3 years ago

Let's see if we can get feedback from the ORM and DBAL people first to see what would be optimal for them, then we can see how easily we can achieve that. No sense trying to make something work they don't actually want.

iluuu1994 commented 3 years ago

Comment from Nikita on the topic:

I find the automatic downcast of enums to their scalar values a bit problematic when taking the overall direction of the language into account. We want less implicit casts, not more. While I'm sure this will work nicely in some cases, it certainly won't in others. I daresay that passing an enum to the $offset parameter of substr() doesn't make sense regardless of whether the enum has an int backing it or not. Explicitly requiring a ->value() call doesn't seem like an undue burden to me.

bwoebi commented 3 years ago

Additionally, if we ever chose to add enumset, IntegerBacked::A | IntegerBacked::B will have different behavior and be a BC break.

iluuu1994 commented 3 years ago

@Crell Your thoughts? ->value is so easy that I think this is completely unnecessary.

beberlei commented 3 years ago

I need two things, a property or method to convert the enum into a scalar value, and a factory method to create an enum instance from the scalar value.

enum MyEnum {
   // ...
}

$value = $enum->value;
$enum = MyEnum::create($value);
iluuu1994 commented 3 years ago

@beberlei The RFC should meet these requirements even after removing type coercion (except that we call create from).

iluuu1994 commented 3 years ago

@Crell Can you share your thoughts?

Arguments for type coercion:

Arguments against type coercion:

Crell commented 3 years ago

I don't have a strong feeling about it either way, to be honest, beyond what ends up most ergonomic for cases that will be converting back and forth a lot. That's mainly DBALs and template engines.

If the DBAL and template engine people don't have a strong case for auto-conversion, then I'm fine with leaving that out. The only reason to include it, IMO, would be if it makes their lives considerably easier.

iluuu1994 commented 3 years ago

Cool, then let's drop it :slightly_smiling_face:

Crell commented 3 years ago

Dropped, and moved to Future Scope as something for a future PHP to possibly reintroduce after we have more experience in the wild.