Shapes: Literals

A shape literal creates an unnamed shape with fields having values as specified by a list of field-initializers. The order of the field-initializers in that list need not be the same as the order of the field specifiers in the shape type's definition. For example:

<?hh

namespace Hack\UserDocumentation\Shapes\Literals\Examples\Literals;

type Point = shape('x' => int, 'y' => int);

class C {
  // All the right hand side expressions are shape literals

  // Can't have a shape as a constant value
  const Point ORIGIN = shape('x' => 0, 'y' => 0);   // initializer rejected

  public static Point $p2 = shape('x' => 0, 'y' => 5);   // initializer okay
  public Point $p3 = shape('x' => 0, 'y' => 5);    // initializer okay
}

function createPoint(int $x = 0, int $y = 0): Point {
  return shape('y' => $y, 'x' => $x); // shape literal, no compile-time constant
}

function run(): void {
  var_dump(createPoint(9, 3));
  var_dump(new C());
}

run();

A shape literal must initialize all the the fields in the shape.

Note that the term literal as used with shapes is a misnomer; the expressions in the field initializers need not be compile-time constants. And even if all the initializers are constant expressions, the resulting shape literal itself is not, so it cannot be used in contexts where such expressions are required.