Skip to content

Commit 40a534c

Browse files
committed
JS nutshell: clarify variables section, clean up code examples
1 parent 59560ba commit 40a534c

File tree

1 file changed

+89
-81
lines changed

1 file changed

+89
-81
lines changed

doc/Language/js-nutshell.pod6

Lines changed: 89 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ start with Node.js again:
3939
=begin code :lang<javascript>
4040
let name = 'Joe';
4141
console.log('What\'s up,' + name + '?');
42-
console.log(`What's up, {name}?`);
42+
console.log(`What's up, ${name}?`);
4343
console.log("What's up, ", name, "?");
4444
=end code
4545
@@ -65,11 +65,13 @@ between the two languages in greater detail.
6565
Variables in Node.js can be defined like this;
6666
6767
=begin code :lang<javascript>
68-
var foo = 1; // Lexically scoped with functions and modules
69-
let foo = 1; // Lexically scoped with blocks
68+
var foo = 1; // Lexically scoped with functions and modules
69+
let foo = 1; // Lexically scoped with blocks
7070
const foo = 1; // Lexically scoped with blocks; constant
7171
72-
global.foo = 1; // Dynamically scoped; global
72+
// No equivalent to Perl 6 dynamic variables exists.
73+
74+
global.foo = 1; // Globally scoped
7375
foo = 1; // Ditto, but implicit; forbidden in strict mode
7476
=end code
7577
@@ -78,26 +80,31 @@ there is no variable hoisting in Perl 6; variables are defined and assigned
7880
at the line they're on, not defined at the top of its scope and later assigned
7981
at that line.
8082
81-
This is how the equivalent types of variables are defined in Perl 6:
83+
In addition to regular variables, in Perl 6 there are what is known as dynamic
84+
variables. Dynamic variables are looked up using the caller's scope, rather
85+
than the outer scope. This is what the equivalent variable declarations look
86+
like in Perl 6:
8287
8388
=begin code
84-
my $foo = 1; # Lexically scoped with blocks
85-
our $foo = 1; # Lexically scoped with blocks and modules
86-
constant foo = 1; # Lexically scoped with blocks and modules; constant
89+
my $foo = 1; # Lexically scoped
90+
our $foo = 1; # Package scoped
91+
my constant foo = 1; # Lexically scoped; constant
92+
constant foo = 1; # Package scoped; constant
93+
94+
my $*foo = 1; # Dynamic variable; lexically scoped
95+
our $*foo = 1; # Dynamic variable; package scoped
8796
88-
my $*foo = 1; # Dynamically scoped with blocks
89-
OUR::<$foo> = 1; # Dynamically scoped with blocks and modules
90-
GLOBAL::<$foo> = 1; # Dynamically scoped; global
97+
GLOBAL::<$foo> := 1; # Globally scoped
9198
=end code
9299
93100
Use C<my> where you'd use C<let>, C<our> for variables you'd define in the
94101
outermost scope needed, and C<constant> where you'd uses C<const>.
95102
96-
Dynamically scoped variables are not referred to in the same way as lexically
97-
scoped ones like they are in Node.js. User-defined ones use either a C<$*>,
98-
C<@*>, C<%*>, or C<&*> twigil. Refer to the documentation on
103+
You may have noticed the C<$> and C<$*> symbols placed before variable names.
104+
These are known as sigils and twigils respectively, and define what container
105+
the variable has. Refer to the documentation on
99106
L<variables|/language/variables> for more information on sigils, twigils, and
100-
variable containers.
107+
containers.
101108
102109
Variables in Node.js can override others from outer scopes with the same name
103110
(though linters will usually complain about it depending on how they're
@@ -110,8 +117,8 @@ function logDupe() {
110117
console.log(foo);
111118
}
112119
113-
logDupe(2); // 2
114-
console.log(foo); // 1
120+
logDupe(2); // OUTPUT: 2
121+
console.log(foo); // OUTPUT: 1
115122
=end code
116123
117124
Perl 6 also allows this:
@@ -123,8 +130,8 @@ sub log-dupe {
123130
say $foo;
124131
}
125132
126-
log-dupe; # 2
127-
say $foo; # 1
133+
log-dupe; # OUTPUT: 2
134+
say $foo; # OUTPUT: 1
128135
=end code
129136
130137
=head2 Operators
@@ -144,11 +151,11 @@ my %map; # This is a hash, roughly equivalent to a JS object or map
144151
my %unbound = %map;
145152
my %bound := %map;
146153
%map<foo> = 'bar';
147-
say %unbound; # {}
148-
say %bound; # {foo => bar}
154+
say %unbound; # OUTPUT: {}
155+
say %bound; # OUTPUT: {foo => bar}
149156
150157
%bound := %unbound;
151-
say %bound; # {}
158+
say %bound; # OUTPUT: {}
152159
=end code
153160
154161
=head3 Equality
@@ -161,18 +168,18 @@ operands are different types, they are both cast to their primitives before
161168
being compared, meaning these will return true:
162169
163170
=begin code :lang<javascript>
164-
console.log(1 == 1); // true
165-
console.log('1' == 1); // true
166-
console.log([] == 0); // true
171+
console.log(1 == 1); // OUTPUT: true
172+
console.log('1' == 1); // OUTPUT: true
173+
console.log([] == 0); // OUTPUT: true
167174
=end code
168175
169176
Similarly, in Perl 6, both operands are cast to Numeric before comparison if
170177
they don't share the same type:
171178
172179
=begin code
173-
say 1 == 1; # True
174-
say '1' == 1; # True
175-
say [1,2,3] == 3; # True, since the array has three elements
180+
say 1 == 1; # OUTPUT: True
181+
say '1' == 1; # OUTPUT: True
182+
say [1,2,3] == 3; # OUTPUT: True, since the array has three elements
176183
=end code
177184
178185
The inverse of C<==> is C<!=>.
@@ -181,8 +188,8 @@ Perl 6 has another operator similar to C<==>: C<eq>. Instead of casting operand
181188
to Numeric if they're different types, C<eq> will cast them to strings:
182189
183190
=begin code
184-
say '1' eq '1'; # True
185-
say 1 eq '1'; # True
191+
say '1' eq '1'; # OUTPUT: True
192+
say 1 eq '1'; # OUTPUT: True
186193
=end code
187194
188195
The inverse of C<eq> is C<ne> or C<!eq>.
@@ -192,26 +199,26 @@ the same value. When comparing objects, this will I<only> return true if they
192199
are the exact same object:
193200
194201
=begin code :lang<javascript>
195-
console.log(1 === 1); // true
196-
console.log('1' === 1); // false
197-
console.log({} === {}); // false
202+
console.log(1 === 1); // OUTPUT: true
203+
console.log('1' === 1); // OUTPUT: false
204+
console.log({} === {}); // OUTPUT: false
198205
199206
let obj = {};
200207
let obj2 = obj;
201-
console.log(obj === obj2); // true;
208+
console.log(obj === obj2); // OUTPUT: true;
202209
=end code
203210
204211
In Perl 6, the operator behaves the same, with one exception: two objects that
205212
have the same value, but different containers, will return false:
206213
207214
=begin code
208-
say 1 === 1; # True
209-
say '1' === 1; # True
210-
say {} === {}; # False
215+
say 1 === 1; # OUTPUT: True
216+
say 'ayy lmao' === 'ayy lmao'; # OUTPUT: True
217+
say {} === {}; # OUTPUT: False
211218
212219
my \hash = {};
213220
my %hash = hash;
214-
say hash === %hash; # False
221+
say hash === %hash; # OUTPUT: False
215222
=end code
216223
217224
In the last case it's the same object, but containers are different, which is
@@ -225,11 +232,11 @@ be used to check for deep equality, which you would normally need to use a
225232
library for in Node.js:
226233
227234
=begin code
228-
say {a => 1} eqv {a => 1}; # True;
235+
say {a => 1} eqv {a => 1}; # OUTPUT: True
229236
230237
my \hash = {};
231238
my %hash := hash;
232-
say hash eqv %hash; # True
239+
say hash eqv %hash; # OUTPUT: True
233240
=end code
234241
235242
In the case you need to check if two variables have the same container and
@@ -238,7 +245,7 @@ value, use the C<=:=> operator.
238245
=begin code
239246
my @arr = [1,2,3];
240247
my @arr2 := @arr; # Bound variables keep the container of the other variable
241-
say @arr =:= @arr2; # True
248+
say @arr =:= @arr2; # OUTPUT: True
242249
=end code
243250
244251
=head3 Smartmatching
@@ -249,14 +256,14 @@ uses: it can be used like C<instanceof> in Node.js, to match a regex, and to
249256
check if a value is a key in a hash, bag, set, or map:
250257
251258
=begin code
252-
say 'foo' ~~ Str; # True
259+
say 'ayy lmao' ~~ Str; # OUTPUT: True
253260
254261
my %hash = a => 1;
255-
say 'a' ~~ %hash; # True
262+
say 'a' ~~ %hash; # OUTPUT: True
256263
257264
my $str = 'abc';
258265
$str ~~ s/abc/def/; # Mutates $str, like foo.replace('abc', 'def')
259-
say $str; # def
266+
say $str; # OUTPUT: def
260267
=end code
261268
262269
While we are talking about C<instanceof>, the equivalent to the C<constructor>
@@ -278,26 +285,26 @@ operators, are cast to their primitives before following through with the
278285
operation, making this possible:
279286
280287
=begin code :lang<javascript>
281-
console.log(1 + 2); // 3
282-
console.log([] + {}); // [object Object]
283-
console.log({} + []); // 0
288+
console.log(1 + 2); // OUTPUT: 3
289+
console.log([] + {}); // OUTPUT: [object Object]
290+
console.log({} + []); // OUTPUT: 0
284291
=end code
285292
286293
In Perl 6, again, they are converted to a Numeric type, as before:
287294
288295
=begin code
289-
say 1 + 2; # 3
290-
say [] + {}; # 0
291-
say {} + [1,2,3]; # 3
296+
say 1 + 2; # OUTPUT: 3
297+
say [] + {}; # OUTPUT: 0
298+
say {} + [1,2,3]; # OUTPUT: 3
292299
=end code
293300
294301
In addition, Perl 6 has C<div> and C<%%>. C<div> behaves like C<int> division in
295302
C, while C<%%> checks if one number is cleanly divisible by another or not:
296303
297304
=begin code
298-
say 4 div 3; # 1
299-
say 4 %% 3; # False
300-
say 6 %% 3; # True
305+
say 4 div 3; # OUTPUT: 1
306+
say 4 %% 3; # OUTPUT: False
307+
say 6 %% 3; # OUTPUT: True
301308
=end code
302309
303310
=head3 Bitwise
@@ -306,26 +313,26 @@ Node.js has C<&>, C<|>, C<^>, C<~>, C«<<», C«>>», C«>>>», and C<~> for bit
306313
operators:
307314
308315
=begin code :lang<javascript>
309-
console.log(1 << 1); // 2
310-
console.log(1 >> 1); // 0
311-
console.log(1 >>> 1); // 0
312-
console.log(1 & 1); // 1
313-
console.log(0 | 1); // 1
314-
console.log(1 ^ 1); // 0
315-
console.log(~1); // -2
316+
console.log(1 << 1); // OUTPUT: 2
317+
console.log(1 >> 1); // OUTPUT: 0
318+
console.log(1 >>> 1); // OUTPUT: 0
319+
console.log(1 & 1); // OUTPUT: 1
320+
console.log(0 | 1); // OUTPUT: 1
321+
console.log(1 ^ 1); // OUTPUT: 0
322+
console.log(~1); // OUTPUT: -2
316323
=end code
317324
318325
In Perl 6, there is no equivalent to C«>>>». All bitwise operators are
319326
prefixed with C<+>, however two's complement uses C<+^> instead of C<~>:
320327
321328
=begin code
322-
say 1 +< 1; # 2
323-
say 1 +> 1; # 0
329+
say 1 +< 1; # OUTPUT: 2
330+
say 1 +> 1; # OUTPUT: 0
324331
# No equivalent for >>>
325-
say 1 +& 1; # 1
326-
say 0 +| 1; # 1
327-
say 1 +^ 1; # 0
328-
say +^1; # -2
332+
say 1 +& 1; # OUTPUT: 1
333+
say 0 +| 1; # OUTPUT: 1
334+
say 1 +^ 1; # OUTPUT: 0
335+
say +^1; # OUTPUT: -2
329336
=end code
330337
331338
=head3 Custom operators and operator overloading
@@ -401,7 +408,7 @@ statements:
401408
my Int $dice-roll = ceiling rand * 12 + ceiling rand * 12;
402409
say 'Snake eyes!' if $dice-roll == 2;
403410
say 'Boxcars!' if $dice-roll == 16;
404-
say "Rolled $dice-roll." if $dice-roll !~~ 2 | 16;
411+
say "Rolled $dice-roll." if $dice-roll != 2 && $dice-roll != 16;
405412
=end code
406413
407414
Perl 6 also has C<when>, which is like C<if>, but if the condition given is
@@ -465,9 +472,9 @@ my Int $score = 0;
465472
for @ranks -> $rank {
466473
# The when blocks implicitly return the last statement they contain.
467474
$score += do given $rank {
468-
when 'Jack' | 'Queen' | 'King' { 10 }
469-
when 'Ace' { $score <= 11 ?? 10 !! 1 }
470-
default { $_ }
475+
when 'Jack' | 'Queen' | 'King' { 10 }
476+
when 'Ace' { $score <= 11 ?? 10 !! 1 }
477+
default { $_ }
471478
};
472479
}
473480
=end code
@@ -506,22 +513,22 @@ for (let ord = 0x61; ord <= 0x7A; ord++) {
506513
// for..in loops (typically used on objects)
507514
for (let letter in letters) {
508515
console.log(letters[letter]);
509-
# OUTPUT:
510-
# A
511-
# B
512-
# C
513-
# etc.
514516
}
517+
# OUTPUT:
518+
# A
519+
# B
520+
# C
521+
# etc.
515522
516523
// for..of loops (typically used on arrays, maps, and sets)
517524
for (let letter of Object.values(letters)) {
518525
console.log(letter);
519-
# OUTPUT:
520-
# A
521-
# B
522-
# C
523-
# etc.
524526
}
527+
# OUTPUT:
528+
# A
529+
# B
530+
# C
531+
# etc.
525532
=end code
526533
527534
Perl 6 C<for> loops most closely resemble C<for..of> loops, since they work on
@@ -742,7 +749,8 @@ a hash. In Perl 6, L<Mu|/type/Mu> is a superclass of all types, though usually
742749
you want to use L<Any|/type/Any> instead, which is a subclass of C<Mu> but also
743750
a superclass of nearly every type, with L<Junction|/type/Junction> being an
744751
exception. When using C<Object> as a hash, L<Hash|/type/Hash> is what you want
745-
to use.
752+
to use. One key difference between C<Object> and C<Hash> is that C<Object>
753+
preserves the order of its keys; C<Hash> does not by default.
746754
747755
There are three types equivalent to C<Array>. L<Array|/type/Array> is most
748756
similar to C<Array>, since it acts as a mutable array. L<List|/type/List> is

0 commit comments

Comments
 (0)