mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 17:41:41 +00:00
Merge pull request #965 from stecman/add-hack-lang
[hack/en] Add english Hack language page
This commit is contained in:
commit
a1d966618b
307
hack.html.markdown
Normal file
307
hack.html.markdown
Normal file
@ -0,0 +1,307 @@
|
||||
---
|
||||
language: Hack
|
||||
contributors:
|
||||
- ["Stephen Holdaway", "https://github.com/stecman"]
|
||||
filename: learnhack.hh
|
||||
---
|
||||
|
||||
Hack is a superset of PHP that runs under a virtual machine called HHVM. Hack
|
||||
is almost completely interoperable with existing PHP code and adds a bunch of
|
||||
useful features from statically typed languages.
|
||||
|
||||
|
||||
Only Hack-specific features are covered here. Details about PHP's syntax are
|
||||
available in the [PHP article](php.html.markdown).
|
||||
|
||||
```php
|
||||
<?hh
|
||||
|
||||
// Hack syntax is only enabled for files starting with an <?hh marker
|
||||
// <?hh markers cannot be interspersed with HTML the way <?php can be.
|
||||
// Using the marker "<?hh //strict" puts the type checker in strict mode.
|
||||
|
||||
|
||||
// Scalar parameter type hints
|
||||
function repeat(string $word, int $count)
|
||||
{
|
||||
$word = trim($word);
|
||||
return str_repeat($word . ' ', $count);
|
||||
}
|
||||
|
||||
// Type hints for return values
|
||||
function add(...$numbers) : int
|
||||
{
|
||||
return array_sum($numbers);
|
||||
}
|
||||
|
||||
// Functions that return nothing are hinted as "void"
|
||||
function truncate(resource $handle) : void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Type hints must explicitly allow being nullable
|
||||
function identity(?string $stringOrNull) : ?string
|
||||
{
|
||||
return $stringOrNull;
|
||||
}
|
||||
|
||||
// Type hints can be specified on class properties
|
||||
class TypeHintedProperties
|
||||
{
|
||||
public ?string $name;
|
||||
|
||||
protected int $id;
|
||||
|
||||
private float $score = 100.0;
|
||||
|
||||
// Hack's type checker enforces that typed properties either have a
|
||||
// default value or are set in the constructor.
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Concise anonymous functions (lambdas)
|
||||
$multiplier = 5;
|
||||
array_map($y ==> $y * $multiplier, [1, 2, 3]);
|
||||
|
||||
|
||||
// Generics
|
||||
class Box<T>
|
||||
{
|
||||
protected T $data;
|
||||
|
||||
public function __construct(T $data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getData(): T {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
function openBox(Box<int> $box) : int
|
||||
{
|
||||
return $box->getData();
|
||||
}
|
||||
|
||||
|
||||
// Shapes
|
||||
//
|
||||
// Hack adds the concept of shapes for defining struct-like arrays with a
|
||||
// guaranteed, type-checked set of keys
|
||||
type Point2D = shape('x' => int, 'y' => int);
|
||||
|
||||
function distance(Point2D $a, Point2D $b) : float
|
||||
{
|
||||
return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2));
|
||||
}
|
||||
|
||||
distance(
|
||||
shape('x' => -1, 'y' => 5),
|
||||
shape('x' => 2, 'y' => 50)
|
||||
);
|
||||
|
||||
|
||||
// Type aliasing
|
||||
//
|
||||
// Hack adds a bunch of type aliasing features for making complex types readable
|
||||
newtype VectorArray = array<int, Vector<int>>;
|
||||
|
||||
// A tuple containing two integers
|
||||
newtype Point = (int, int);
|
||||
|
||||
function addPoints(Point $p1, Point $p2) : Point
|
||||
{
|
||||
return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]);
|
||||
}
|
||||
|
||||
addPoints(
|
||||
tuple(1, 2),
|
||||
tuple(5, 6)
|
||||
);
|
||||
|
||||
|
||||
// First-class enums
|
||||
enum RoadType : int
|
||||
{
|
||||
Road = 0;
|
||||
Street = 1;
|
||||
Avenue = 2;
|
||||
Boulevard = 3;
|
||||
}
|
||||
|
||||
function getRoadType() : RoadType
|
||||
{
|
||||
return RoadType::Avenue;
|
||||
}
|
||||
|
||||
|
||||
// Constructor argument promotion
|
||||
//
|
||||
// To avoid boilerplate property and constructor definitions that only set
|
||||
// properties, Hack adds a concise syntax for defining properties and a
|
||||
// constructor at the same time.
|
||||
class ArgumentPromotion
|
||||
{
|
||||
public function __construct(public string $name,
|
||||
protected int $age,
|
||||
private bool $isAwesome) {}
|
||||
}
|
||||
|
||||
class WithoutArugmentPromotion
|
||||
{
|
||||
public string $name;
|
||||
|
||||
protected int $age;
|
||||
|
||||
private bool $isAwesome;
|
||||
|
||||
public function __construct(string $name, int $age, bool $isAwesome)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->age = $age;
|
||||
$this->isAwesome = $isAwesome;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Co-oprerative multi-tasking
|
||||
//
|
||||
// Two new keywords "async" and "await" can be used to perform mutli-tasking
|
||||
// Note that this does not involve threads - it just allows transfer of control
|
||||
async function cooperativePrint(int $start, int $end) : Awaitable<void>
|
||||
{
|
||||
for ($i = $start; $i <= $end; $i++) {
|
||||
echo "$i ";
|
||||
|
||||
// Give other tasks a chance to do something
|
||||
await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// This prints "1 4 7 2 5 8 3 6 9"
|
||||
AwaitAllWaitHandle::fromArray([
|
||||
cooperativePrint(1, 3),
|
||||
cooperativePrint(4, 6),
|
||||
cooperativePrint(7, 9)
|
||||
])->getWaitHandle()->join();
|
||||
|
||||
|
||||
// Attributes
|
||||
//
|
||||
// Attributes are a form of metadata for functions. Hack provides some
|
||||
// special built-in attributes that introduce useful behaviour.
|
||||
|
||||
// The __Memoize special attribute causes the result of a function to be cached
|
||||
<<__Memoize>>
|
||||
function doExpensiveTask() : ?string
|
||||
{
|
||||
return file_get_contents('http://example.com');
|
||||
}
|
||||
|
||||
// The function's body is only executed once here:
|
||||
doExpensiveTask();
|
||||
doExpensiveTask();
|
||||
|
||||
|
||||
// The __ConsistentConstruct special attribute signals the Hack type checker to
|
||||
// ensure that the signature of __construct is the same for all subclasses.
|
||||
<<__ConsistentConstruct>>
|
||||
class ConsistentFoo
|
||||
{
|
||||
public function __construct(int $x, float $y)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function someMethod()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class ConsistentBar extends ConsistentFoo
|
||||
{
|
||||
public function __construct(int $x, float $y)
|
||||
{
|
||||
// Hack's type checker enforces that parent constructors are called
|
||||
parent::__construct($x, $y);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
// The __Override annotation is an optional signal for the Hack type
|
||||
// checker to enforce that this method is overriding a method in a parent
|
||||
// or trait. If not, this will error.
|
||||
<<__Override>>
|
||||
public function someMethod()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidFooSubclass extends ConsistentFoo
|
||||
{
|
||||
// Not matching the parent constructor will cause a type checker error:
|
||||
//
|
||||
// "This object is of type ConsistentBaz. It is incompatible with this object
|
||||
// of type ConsistentFoo because some of their methods are incompatible"
|
||||
//
|
||||
public function __construct(float $x)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Using the __Override annotation on a non-overriden method will cause a
|
||||
// type checker error:
|
||||
//
|
||||
// "InvalidFooSubclass::otherMethod() is marked as override; no non-private
|
||||
// parent definition found or overridden parent is defined in non-<?hh code"
|
||||
//
|
||||
<<__Override>>
|
||||
public function otherMethod()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Traits can implement interfaces (standard PHP does not support this)
|
||||
interface KittenInterface
|
||||
{
|
||||
public function play() : void;
|
||||
}
|
||||
|
||||
trait CatTrait implements KittenInterface
|
||||
{
|
||||
public function play() : void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class Samuel
|
||||
{
|
||||
use CatTrait;
|
||||
}
|
||||
|
||||
|
||||
$cat = new Samuel();
|
||||
$cat instanceof KittenInterface === true; // True
|
||||
|
||||
```
|
||||
|
||||
## More Information
|
||||
|
||||
Visit the [Hack language reference](http://docs.hhvm.com/manual/en/hacklangref.php)
|
||||
for detailed explainations of the features Hack adds to PHP, or the [official Hack website](http://hacklang.org/)
|
||||
for more general information.
|
||||
|
||||
Visit the [official HHVM website](http://hhvm.com/) for HHVM installation instructions.
|
||||
|
||||
Visit [Hack's unsupported PHP features article](http://docs.hhvm.com/manual/en/hack.unsupported.php).]
|
||||
for details on the backwards incompatibility between Hack and PHP.
|
Loading…
Reference in New Issue
Block a user