1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
---
language: Hack
contributors:
- ["Stephen Holdaway", "https://github.com/stecman"]
- ["David Lima", "https://github.com/davelima"]
- ["Jerome Meinke", "https://github.com/jmeinke"]
filename: learnhack.hh
---
Hack ist eine von Facebook neu entwickelte Programmiersprache auf Basis von PHP.
Sie wird von der HipHop Virtual Machine (HHVM) ausgeführt. Die HHVM kann
aufgrund der Ähnlichkeit der Programmiersprachen nicht nur Hack, sondern auch
PHP-Code ausführen. Der wesentliche Unterschied zu PHP besteht in der statischen
Typisierung der Sprache, die eine wesentlich höhere Performance erlaubt.
Hier werden nur Hack-spezifische Eigenschaften beschrieben. Details über PHP's
Syntax findet man im [PHP Artikel](http://learnxinyminutes.com/docs/php/) dieser
Seite.
```php
<?hh
// Hack-Syntax ist nur für Dateien aktiv, die mit dem <?hh Prefix starten.
// Der <?hh Prefix kann nicht wie <?php mit HTML gemischt werden.
// Benutzung von "<?hh //strict" aktiviert den Strikt-Modus des Type-Checkers.
// Typisierung für Funktions-Argumente
function repeat(string $word, int $count)
{
$word = trim($word);
return str_repeat($word . ' ', $count);
}
// Typisierung für Rückgabewerte
function add(...$numbers) : int
{
return array_sum($numbers);
}
// Funktionen ohne Rückgabewert, werden mit "void" typisiert
function truncate(resource $handle) : void
{
// ...
}
// Typisierung unterstützt die explizit optionale Ein- / Ausgabe von "null"
function identity(?string $stringOrNull) : ?string
{
return $stringOrNull;
}
// Typisierung von Klassen-Eigenschaften
class TypeHintedProperties
{
public ?string $name;
protected int $id;
private float $score = 100.0;
// Hack erfordert es, dass typisierte Eigenschaften (also "non-null")
// einen Default-Wert haben oder im Konstruktor initialisiert werden.
public function __construct(int $id)
{
$this->id = $id;
}
}
// Kurzgefasste anonyme Funktionen (lambdas)
$multiplier = 5;
array_map($y ==> $y * $multiplier, [1, 2, 3]);
// Weitere, spezielle Felder (Generics)
// Diese kann man sich als ein zugreifbares Interface vorstellen
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();
}
// Formen
//
// Hack fügt das Konzept von Formen hinzu, wie struct-ähnliche arrays
// mit einer typ-geprüften Menge von Schlüsseln
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)
);
// Typen-Definition bzw. Aliasing
//
// Hack erlaubt es Typen zu definieren und sorgt somit für bessere Lesbarkeit
newtype VectorArray = array<int, Vector<int>>;
// Ein Tupel mit zwei Integern
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)
);
// Erstklassige Aufzählungen (enums)
enum RoadType : int
{
Road = 0;
Street = 1;
Avenue = 2;
Boulevard = 3;
}
function getRoadType() : RoadType
{
return RoadType::Avenue;
}
// Automatische Erstellung von Klassen-Eigenschaften durch Konstruktor-Argumente
//
// Wiederkehrende Definitionen von Klassen-Eigenschaften können durch die Hack-
// Syntax vermieden werden. Hack erlaubt es die Klassen-Eigenschaften über
// Argumente des Konstruktors zu definieren.
class ArgumentPromotion
{
public function __construct(public string $name,
protected int $age,
private bool $isAwesome) {}
}
class WithoutArgumentPromotion
{
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;
}
}
// Kooperatives Multitasking
//
// Die Schlüsselworte "async" and "await" führen Multitasking ein.
// Achtung, hier werden keine Threads benutzt, sondern nur Aktivität getauscht.
async function cooperativePrint(int $start, int $end) : Awaitable<void>
{
for ($i = $start; $i <= $end; $i++) {
echo "$i ";
// Geben anderen Tasks die Möglichkeit aktiv zu werden
await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
}
}
// Die Ausgabe von folgendem Code ist "1 4 7 2 5 8 3 6 9"
AwaitAllWaitHandle::fromArray([
cooperativePrint(1, 3),
cooperativePrint(4, 6),
cooperativePrint(7, 9)
])->getWaitHandle()->join();
// Attribute
//
// Attribute repräsentieren eine Form von Metadaten für Funktionen.
// Hack bietet Spezial-Attribute, die nützliche Eigenschaften mit sich bringen.
// Das __Memoize Attribut erlaubt es die Ausgabe einer Funktion zu cachen.
<<__Memoize>>
function doExpensiveTask() : ?string
{
return file_get_contents('http://example.com');
}
// Der Funktionsrumpf wird im Folgenden nur ein einziges mal ausgeführt:
doExpensiveTask();
doExpensiveTask();
// Das __ConsistentConstruct Attribut signalisiert dem type-checker, dass
// die Funktionsdeklaration von __construct für alle Unterklassen dieselbe ist.
<<__ConsistentConstruct>>
class ConsistentFoo
{
public function __construct(int $x, float $y)
{
// ...
}
public function someMethod()
{
// ...
}
}
class ConsistentBar extends ConsistentFoo
{
public function __construct(int $x, float $y)
{
// Der Type-checker erzwingt den Aufruf des Eltern-Klassen-Konstruktors
parent::__construct($x, $y);
// ...
}
// Das __Override Attribut ist ein optionales Signal an den Type-Checker,
// das erzwingt, dass die annotierte Methode die Methode der Eltern-Klasse
// oder des Traits verändert.
<<__Override>>
public function someMethod()
{
// ...
}
}
class InvalidFooSubclass extends ConsistentFoo
{
// Wenn der Konstruktor der Eltern-Klasse nicht übernommen wird,
// wird der Type-Checker einen Fehler ausgeben:
//
// "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)
{
// ...
}
// Auch bei der Benutzung des __Override Attributs für eine nicht veränderte
// Methode wird vom Type-Checker eine Fehler ausgegeben:
//
// "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()
{
// ...
}
}
// Ein Trait ist ein Begriff aus der objektorientierten Programmierung und
// beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen,
// ähnlich einer Klasse.
// Anders als in PHP können Traits auch als Schnittstellen (Interfaces)
// implementiert werden und selbst Schnittstellen implementieren.
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
```
## Weitere Informationen
Die Hack [Programmiersprachen-Referenz](http://docs.hhvm.com/manual/de/hacklangref.php)
erklärt die neuen Eigenschaften der Sprache detailliert auf Englisch. Für
allgemeine Informationen kann man auch die offizielle Webseite [hacklang.org](http://hacklang.org/)
besuchen.
Die offizielle Webseite [hhvm.com](http://hhvm.com/) bietet Infos zum Download
und zur Installation der HHVM.
Hack's [nicht-untersützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php)
werden im offiziellen Handbuch beschrieben.
|