rfc:tagged_unions

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
rfc:tagged_unions [2020/12/05 20:21] crellrfc:tagged_unions [2023/01/18 18:40] (current) crell
Line 24: Line 24:
 Tagged cases are mutually exclusive with Scalar Cases.  If an Enum has at least one Tagged Case, it may not have any Scalar Cases and vice versa.  However, the same Enum may consist of any number of Tagged and Unit Cases. Tagged cases are mutually exclusive with Scalar Cases.  If an Enum has at least one Tagged Case, it may not have any Scalar Cases and vice versa.  However, the same Enum may consist of any number of Tagged and Unit Cases.
  
-Associated values are defined using constructor property promotion.+If two Tagged Case instances have the same associated value, the object instance will be reused.  That means two instances that have the same associated values will pass both a ''%%==%%'' check and a ''%%===%%'' check.
  
 <code php> <code php>
 enum Distance { enum Distance {
-    case Kilometers(public int $km); +    case Kilometers(int $km); 
-    case Miles(public int $miles);+    case Miles(int $miles);
 } }
  
Line 38: Line 38:
 print $my_walk->miles; // prints "500" print $my_walk->miles; // prints "500"
  
-$my_walk === $next_walk; // FALSE!+$my_walk == $next_walk; // TRUE! 
 +$my_walk === $next_walk; // TRUE!
 </code> </code>
  
-Tagged Cases may not implement a full constructor. However, they may list parameters that will be auto-promoted to properties using constructor promotionThe visibility modifier is required. Cases may not implement properties other than promoted properties.+Tagged Cases may not implement a full constructor.  The associated values specified will be available as public readonly properties on the case object Associated values may have property-targeting attributes associated with them.
  
 The Enum Type itself may not define associated values. Only a Case may do so. The Enum Type itself may not define associated values. Only a Case may do so.
- 
-Associated values are always read-only, both internally to the class and externally. Therefore, making them public does not pose a risk of 3rd party code modifying them inadvertently. They may, however, have attributes associated with them like any other property. 
  
 On a Tagged Case enumeration, the ''%%cases()%%'' method is not available and will throw a ''%%TypeError%%''. Since Tagged Cases are technically unbounded, the method has no logical sense. On a Tagged Case enumeration, the ''%%cases()%%'' method is not available and will throw a ''%%TypeError%%''. Since Tagged Cases are technically unbounded, the method has no logical sense.
Line 63: Line 62:
   // This is a Unit Case.   // This is a Unit Case.
   case None {   case None {
-    public function bind(callable $f) +    public function bind(callable $f)
     {     {
       return $this;       return $this;
Line 70: Line 69:
  
   // This is a Tagged Case.   // This is a Tagged Case.
-  case Some(private mixed $value) {+  case Some(mixed $value) {
     // Note that the return type can be the Enum itself, thus restricting the return     // Note that the return type can be the Enum itself, thus restricting the return
     // value to one of the enumerated types.     // value to one of the enumerated types.
Line 79: Line 78:
     }     }
   };   };
- 
-  // This method is available on both None and Some. 
-  public function value(): mixed { 
-    if ($this instanceof None) { 
-      throw new Exception(); 
-    } 
-    return $this->val; 
-  } 
 } }
 </code> </code>
Line 104: Line 95:
  
 enum Command { enum Command {
-  case Move(public CardinalDirection $direction, int $distance); +  case Move(CardinalDirection $direction, int $distance); 
-  case Turn(public Direction $dir);+  case Turn(Direction $dir);
   case Shoot;   case Shoot;
 } }
 </code> </code>
  
 +=== Static analysis type tracking ===
 +
 +PHP's types could be represented with an enum like so:
 +
 +<PHP>
 +enum Type
 +{
 +  case Int;
 +  case Float;
 +  case String;
 +  case Array;
 +  case Bool;
 +  case Object(string $class);
 +}
 +</PHP>
 +
 +(I really have had to do something like that before.)  Combined with pattern matching, this would allow for a very robust way to handle objects being special and having additional context.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 117: Line 125:
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-PHP 8.1.+PHP 8.3.
  
 ===== Open Issues ===== ===== Open Issues =====
rfc/tagged_unions.1607199665.txt.gz · Last modified: 2020/12/05 20:21 by crell