Skip to content

Instantly share code, notes, and snippets.

@bcherny
Last active January 16, 2018 06:34
Show Gist options
  • Select an option

  • Save bcherny/3dafa0a8ebf581aca863215945cd0476 to your computer and use it in GitHub Desktop.

Select an option

Save bcherny/3dafa0a8ebf581aca863215945cd0476 to your computer and use it in GitHub Desktop.
Hack Lang Spec Notes

Some notes while reading through the Hack Lang spec.

4. Basic Concepts

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 &array in 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.
  • The clone operator does a shallow clone on its argument.
  • Hack supports these scopes: Script, Function, Class, Interface, Namespace, Catch clause (like in JS), (not Block!).

5. Types

  • 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::keyExists to check if a shape has a nullable key set before using it

  • Use type to create a structurally typed type alias

  • Use newtype to create a nominally typed type alias. A newtype generates 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, newtype behaves like a regular type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment