Some notes while reading through the Hack Lang spec.
VSlot -> VStore -> value: scalar | null
\_ type tag: Null, Bool, Int, Float, Str, Arr, Arr-D, Obj, or Res
eg. `$a = true;`
VSlot -> VStore -> value: HStore | null
\_ type tag
eg. `$a = {};`
HStore -> [VSlot]
eg. array elements, instance properties
- byRef
&- Allows assigning value types by reference - In Hack, strings and arrays are value types (unlike in JS)
- Sometimes arrays are "deferred", and behave like arrays in JS (which is not quite the same as
&arrayin Hack). This is a performance optimization to make copies close to zero-cost. As soon as you mutate the copied array/update its cursor/add more than 1 reference to an array element, Hack will be forced to copy the array (so it behaves like a value type). This is called copy-on-write. - Sometimes strings are "deferred" too. The same rules as for arrays apply for forcing a full copy.
- Sometimes arrays are "deferred", and behave like arrays in JS (which is not quite the same as
- The
cloneoperator does a shallow clone on its argument. - Hack supports these scopes: Script, Function, Class, Interface, Namespace, Catch clause (like in JS), (not Block!).
-
Kinds of types:
- Scalar: boolean, integer, floating-point, numeric, string, array key, null, and enumerated
- Composite: array, class, interface, tuple, shape, closure, resource, and nullable
- Void
-
Useful functions for debugging types:
gettype,is_type,settype,var_dump. -
Type constants are like static members on a class. Eg.
interface I { const type T = int; } class C1 implements I {} class C2 extends C1 {} // I::T === C1::T === C2::T
-
Roughly:
type bool = true | false type int = -9223372036854775808 .. 9223372036854775807 type float = .. type num = int | float type string = array int string type arraykey = int | string type null = null type void = void type array a = [(int | string) -> a] -- Hack arrays are heterogeneous type vector a = [int -> a] type map a b = [a -> b]
-
A tuple must contain 2 or more elements (you can declare a tuple literal with 1 element, but you can't declare the type for it)
-
Use
Shapes::keyExiststo check if a shape has a nullable key set before using it -
Use
typeto create a structurally typed type alias -
Use
newtypeto create a nominally typed type alias. Anewtypegenerates an opaque type, and does not allow any consumers outside of the file it was defined in to know anything about what it aliases. When used as part of a type constraint,newtypebehaves like a regulartype.