-
Notifications
You must be signed in to change notification settings - Fork 2
/
scala_ref.txt
8436 lines (5728 loc) · 256 KB
/
scala_ref.txt
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*Preface
Scala is a Java-like programming language which unifies
object-oriented and functional programming. It is a pure
object-oriented language in the sense that every value is an
object. Types and behavior of objects are described by
classes. Classes can be composed using mixin composition. Scala is
designed to work seamlessly with two less pure but mainstream
object-oriented languages -- Java and C.
Scala is a functional language in the sense that every function is a
value. Nesting of function definitions and higher-order functions are
naturally supported. Scala also supports a general notion of pattern
matching which can model the algebraic types used in many functional
languages.
Scala has been designed to interoperate seamlessly with Java (an
alternative implementation of Scala also works for .NET). Scala
classes can call Java methods, create Java objects, inherit from Java
classes and implement Java interfaces. None of this requires interface
definitions or glue code.
Scala has been developed from 2001 in the programming methods
laboratory at EPFL. Version 1.0 was released in November 2003. This
document describes the second version of the language, which was
released in March 2006. It acts a reference for the language
definition and some core library modules. It is not intended to teach
Scala or its concepts; for this there are other documents
.
Scala has been a collective effort of many people. The design and the
implementation of version 1.0 was completed by Philippe Altherr,
Vincent Cremet, Gilles Dubochet, Burak Emir, Stephane Micheloud,
Nikolay Mihaylov, Michel Schinz, Erik Stenman, Matthias Zenger, and
the author. Iulian Dragos, Gilles Dubochet, Philipp Haller, Sean
McDirmid, Lex Spoon, and Geoffrey Washburn joined in the effort to
develop the second version of the language and tools. Gilad Bracha,
Craig Chambers, Erik Ernst, Matthias Felleisen, Shriram Krishnamurti,
Gary Leavens, Sebastian Maneth, Erik Meijer, Klaus Ostermann, Didier
Remy, Mads Torgersen, and Philip Wadler have shaped the design of
the language through lively and inspiring discussions and comments on
previous versions of this document. The contributors to the Scala
mailing list have also given very useful feedback that helped us
improve the language and its tools.
Lexical Syntax
Scala programs are written using the Unicode Basic Multilingual Plane
(bmp) character set; Unicode supplementary characters are not
presently supported. This chapter defines the two modes of Scala's
lexical syntax, the Scala mode and the xml mode. If not
otherwise mentioned, the following descriptions of Scala tokens refer
to Scala mode, and literal characters `c' refer to the ASCII fragment
0000007F.
In Scala mode, Unicode escapes are replaced by the corresponding
Unicode character with the given hexadecimal code.
UnicodeEscape ::= uu hexDigit hexDigit hexDigit hexDigit
hexDigit ::= `0' `9' `A' `F' `a' `f'
To construct tokens, characters are distinguished according to the following classes
(Unicode general category given in parentheses):
Whitespace characters. 0020 0009 000D 000A
Letters, which include lower case letters(Ll), upper case letters(Lu), titlecase letters(Lt), other letters(Lo), letter numerals(Nl) and the
two characters 0024 and 005F which
both count as upper case letters
Digits `9'@.
Parentheses `)' `[' `]' `' `'@.
Delimiter characters `'' `"' `.' `;' `,'@.
Operator characters. These consist of all printable ASCII characters 0020007F.
which are in none of the sets above, mathematical symbols(Sm) and other symbols(So).
Identifiers
lstlisting
op ::= opchar opchar
varid ::= lower idrest
plainid ::= upper idrest
varid
op
id ::= plainid
`' stringLit `'
idrest ::= letter digit [`_' op]
There are three ways to form an identifier. First, an identifier can
start with a letter which can be followed by an arbitrary sequence of
letters and digits. This may be followed by underscore `_@'
characters and another string composed of either letters and digits or
of operator characters. Second, an identifier can start with an operator
character followed by an arbitrary sequence of operator characters.
The preceding two forms are called plain identifiers. Finally,
an identifier may also be formed by an arbitrary string between
back-quotes (host systems may impose some restrictions on which
strings are legal for identifiers). The identifier then is composed
of all characters excluding the backquotes themselves.
As usual, a longest match rule applies. For instance, the string
big_bob++=`def`
decomposes into the three identifiers _bob@, ++=@, and
def. The rules for pattern matching further distinguish between
variable identifiers, which start with a lower case letter, and
constant identifiers, which do not.
The `[mathescape=false]@ character is reserved
for compiler-synthesized identifiers. User programs should not define
identifiers which contain `[mathescape=false]@
characters.
The following names are reserved words instead of being members of the
syntactic class id of lexical identifiers.
abstract case catch class def
do else extends false final
finally for forSome if implicit
import lazy match new null
object override package private protected
return sealed super this throw
trait try true type val
var while with yield
_ : = => <- <: <
The Unicode operators 21D2 `' and 2190
`', which have the ASCII equivalents `and
`<-@', are also reserved.
Here are examples of identifiers:
x Object maxIndex p2p empty_?
+ `yield` _y dot_product_*
__system _MAX_LEN_
Backquote-enclosed strings are a solution when one needs to
access Java identifiers that are reserved words in Scala. For
instance, the statement .yield()@ is illegal, since
yield is a reserved word in Scala. However, here's a
work-around:
Thread.`yield`()
Newline Characters
lstlisting
semi ::= `;' nl nl
Scala is a line-oriented language where statements may be terminated by
semi-colons or newlines. A newline in a Scala source text is treated
as the special token ``if the three following
criteria are satisfied:
The token immediately preceding the newline can terminate a statement.
The token immediately following the newline can begin a statement.
The token appears in a region where newlines are enabled.
The tokens that can terminate a statement are: literals, identifiers
and the following delimiters and reserved words:
this null true false return type <xml-start>
_ ) ]
The tokens that can begin a statement are all Scala tokens except
the following delimiters and reserved words:
catch else extends finally forSome match
with yield , . ; : = => <- <: <
>: # [ ) ]
A token can begin a statement only if followed by a
or token.
Newlines are enabled in:
all of a Scala source file, except for nested regions where newlines
are disabled, and
the interval between matching @ and @ brace tokens,
except for nested regions where newlines are disabled.
Newlines are disabled in:
the interval between matching (@ and )@ parenthesis tokens, except for nested regions where newlines are enabled, and
the interval between matching [@ and ]@ bracket tokens,
except for nested regions where newlines are enabled.
The interval between a token and its matching
token, except for nested regions where newlines are
enabled.
Any regions analyzed in XML mode (sec::xmlMode).
Note that the brace characters of ...@ escapes in XML and
string literals are not tokens,
and therefore do not enclose a region where newlines
are enabled.
Normally, only a single nl token is inserted between two
consecutive non-newline tokens which are on different lines, even if there are multiple lines
between the two tokens. However, if two tokens are separated by at
least one completely blank line (i.e a line which contains no
printable characters), then two nl tokens are inserted.
The Scala grammar (given in full in Appendix )
contains productions where optional nl tokens, but not
semicolons, are accepted. This has the effect that a newline in one of these
positions does not terminate an expression or statement. These positions can
be summarized as follows:
Multiple newline tokens are accepted in the following places (note
that a semicolon in place of the newline would be illegal in every one
of these cases):
[--]
between the condition of an conditional expression
(sec:cond) or while loop (sec:while) and the next
following expression,
[--]
between the enumerators of a for-comprehension (sec:for-comprehensions)
and the next following expression, and
[--]
after the initial keyword in a type definition or
declaration (sec:typedcl).
A single new line token is accepted
[--]
in front of an opening brace ``'', if that brace is a legal
continuation of the current statement or expression,
[--]
after an infix operator, if the first token on the next line can
start an expression (sec:infix-operations),
[--]
in front of a parameter clause (sec:funsigs), and
[--]
after an annotation (sec:annotations).
The following code contains four well-formed statements, each
on two lines. The newline tokens between the two lines are not
treated as statement separators.
if (x > 0)
x = x - 1
while (x > 0)
x = x / 2
for (x <- 1 to 10)
println(x)
type
IntList = List[Int]
The following code designates an anonymous class
new Iterator[Int]
private var x = 0
def hasNext = true
def next = x += 1; x
With an additional newline character, the same code is interpreted as
an object creation followed by a local block:
new Iterator[Int]
private var x = 0
def hasNext = true
def next = x += 1; x
The following code designates a single expression:
x < 0
x > 10
With an additional newline character, the same code is interpreted as
two expressions:
x < 0
x > 10
The following code designates a single, curried function definition:
def func(x: Int)
(y: Int) = x + y
With an additional newline character, the same code is interpreted as
an abstract function definition and a syntactically illegal statement:
def func(x: Int)
(y: Int) = x + y
The following code designates an attributed definition:
@serializable
protected class Data ...
With an additional newline character, the same code is interpreted as
an attribute and a separate statement (which is syntactically
illegal).
@serializable
protected class Data ...
Literals
There are literals for integer numbers, floating point numbers,
characters, booleans, symbols, strings. The syntax of these literals is in
each case as in Java.
say that we take values from Java, give examples of some lits in
particular float and double.
lstlisting
Literal ::= [`-'] integerLiteral
[`-'] floatingPointLiteral
booleanLiteral
characterLiteral
stringLiteral
symbolLiteral
`null'
Integer Literals
lstlisting
integerLiteral ::= (decimalNumeral hexNumeral octalNumeral) [`L' `l']
decimalNumeral ::= `0' nonZeroDigit digit
hexNumeral ::= `0' `x' hexDigit hexDigit
octalNumeral ::= `0' octalDigit octalDigit
digit ::= `0' nonZeroDigit
nonZeroDigit ::= `1' `9'
octalDigit ::= `0' `7'
Integer literals are usually of type , or of type
when followed by a or
suffix. Values of type are all integer
numbers between and , inclusive. Values of
type are all integer numbers between and
, inclusive. A compile-time error occurs if an integer literal
denotes a number outside these ranges.
However, if the expected type (sec:expr-typing) of a literal
in an expression is either Byte, Short, or Char
and the integer number fits in the numeric range defined by the type,
then the number is converted to type and the literal's type
is . The numeric ranges given by these types are:
p2cml
& to
& to
& to
Here are some integer literals:
0 21 0xFFFFFFFF 0777L
Floating Point Literals
lstlisting
floatingPointLiteral ::= digit digit `.' digit [exponentPart] [floatType]
`.' digit digit [exponentPart] [floatType]
digit digit exponentPart [floatType]
digit digit [exponentPart] floatType
exponentPart ::= (`E' `e') [`+' `-'] digit digit
floatType ::= `F' `f' `D' `d'
Floating point literals are of type when followed by
a floating point type suffix or , and are
of type otherwise. The type
consists of all IEEE 754 32-bit single-precision binary floating point
values, whereas the type consists of all IEEE 754
64-bit double-precision binary floating point values.
If a floating point literal in a program is followed by a token
starting with a letter, there must be at least one intervening
whitespace character between the two tokens.
Here are some floating point literals:
0.0 1e30f 3.14159f 1.0e-100 .1
The phrase `1.toString@' parses as three different tokens:
``.@', and `On the
other hand, if a space is inserted after the period, the phrase
`1. toString@' parses as the floating point literal
`1.@' followed by the identifier `
Boolean Literals
lstlisting
booleanLiteral ::= `true' `false'
The boolean literals and are
members of type .
Character Literals
lstlisting
characterLiteral ::= `' printableChar `'
`' charEscapeSeq `'
A character literal is a single character enclosed in quotes.
The character is either a printable unicode character or is described
by an escape sequence (sec:escapes).
Here are some character literals:
'a' '''
Note that `is not a valid character literal because
Unicode conversion is done before literal parsing and the Unicode
character 000A@ (line feed) is not a printable
character. One can use instead the escape sequence `or
the octal escape `2@' (sec:escapes).
String Literals
lstlisting
stringLiteral ::= `' stringElement `'
stringElement ::= printableCharNoDoubleQuote charEscapeSeq
A string literal is a sequence of characters in double quotes. The
characters are either printable unicode character or are described by
escape sequences (sec:escapes). If the string literal
contains a double quote character, it must be escaped,
i.e. @. The value of a string literal is an instance of
class .
Here are some string literals:
"Hello,!"
"This string contains a character."
*Multi-Line String Literals
lstlisting
stringLiteral ::= `"""' multiLineChars `"""'
multiLineChars ::= ['"'] ['"'] charNoDoubleQuote `"'
A multi-line string literal is a sequence of characters enclosed in
triple quotes """ ... """@. The sequence of characters is
arbitrary, except that it may contain three or more consuctive quote characters
only at the very end. Characters
must not necessarily be printable; newlines or other
control characters are also permitted. Unicode escapes work as everywhere else, but none
of the escape sequences in (sec:escapes) is interpreted.
Here is a multi-line string literal:
"""the present string
spans three
lines."""
This would produce the string:
the present string
spans three
lines.
The Scala library contains a utility method
which can be used to strip leading whitespace from multi-line strings.
The expression
"""the present string
spans three
lines.""".stripMargin
evaluates to
the present string
spans three
lines.
Method is defined in class
.collection.immutable.StringLike@.
Because there is a predefined
implicit conversion (sec:impl-conv) from String to
StringLike, the method is applicable to all strings.
Escape Sequences
The following escape sequences are recognized in character and string
literals.
p2cmll
& 0008@: backspace BS
& 0009@: horizontal tab HT
& 000a@: linefeed LF
& 000c@: form feed FF
& 000d@: carriage return CR
@ & 0022@: double quote "
@ & 0027@: single quote '
@ & 005c@: backslash
A character with Unicode between 0 and 255 may also be represented by
an octal escape, i.e. a backslash `followed by a
sequence of up to three octal characters.
It is a compile time error if a backslash character in a character or
string literal does not start a valid escape sequence.
Symbol literals
lstlisting
symbolLiteral ::= `'' plainid
A symbol literal is a shorthand for the expression
.Symbol("")@. is a case class
(sec:case-classes), which is defined as follows.
package scala
final case class Symbol private (name: String)
override def toString: String = "'" + name
The method of companion object
caches weak references to , thus ensuring that
identical symbol literals are equivalent with respect to reference
equality.
Whitespace and Comments
Tokens may be separated by whitespace characters
and/or comments. Comments come in two forms:
A single-line comment is a sequence of characters which starts with
//@ and extends to the end of the line.
A multi-line comment is a sequence of characters between
/*@ and */@. Multi-line comments may be nested,
but are required to be properly nested. Therefore, a comment like
/* /* */@ will be rejected as having an unterminated
comment.
XML mode
In order to allow literal inclusion of XML fragments, lexical analysis
switches from Scala mode to XML mode when encountering an opening
angle bracket '<' in the following circumstance: The '<' must be
preceded either by whitespace, an opening parenthesis or an opening
brace and immediately followed by a character starting an XML name.
lstlisting
( whitespace `(' `' ) `<' (XNameStart `!' `?')
XNameStart ::= `_' BaseChar Ideographic `:'
The scanner switches from XML mode to Scala mode if either
the XML expression or the XML pattern started by the initial '<' has been
successfully parsed, or if
the parser encounters an embedded Scala expression or pattern and
forces the Scanner
back to normal mode, until the Scala expression or pattern is
successfully parsed. In this case, since code and XML fragments can be
nested, the parser has to maintain a stack that reflects the nesting
of XML and Scala expressions adequately.
Note that no Scala tokens are constructed in XML mode, and that comments are interpreted
as text.
The following value definition uses an XML literal with two embedded
Scala expressions
val b = <book>
<title>The Scala Language Specification</title>
<version>scalaBook.version</version>
<authors>scalaBook.authors.mkList("", ", ", "")</authors>
</book>
Identifiers, Names and Scopes
Names in Scala identify types, values, methods, and classes which are
collectively called entities. Names are introduced by local
definitions and declarations (sec:defs), inheritance (sec:members),
import clauses (sec:import), or package clauses
(sec:packagings) which are collectively called
bindings.
Bindings of different kinds have a precedence defined on them:
Definitions and declarations that are local, inherited, or made
available by a package clause in the same compilation unit where the
definition occurs have highest precedence.
Explicit imports have next highest precedence.
Wildcard imports have next highest precedence.
Definitions made available by a package clause not in the
compilation unit where the definition occurs have lowest precedence.
There are two different name spaces, one for types (sec:types)
and one for terms (sec:exprs). The same name may designate a
type and a term, depending on the context where the name is used.
A binding has a scope in which the entity defined by a single
name can be accessed using a simple name. Scopes are nested. A binding
in some inner scope shadows bindings of lower precedence in the
same scope as well as bindings of the same or lower precedence in outer
scopes.
Note that shadowing is only a partial order. In a situation like
val x = 1;
import p.x;
x
neither binding of x shadows the other. Consequently, the
reference to x in the third line above would be ambiguous.
A reference to an unqualified (type- or term-) identifier is bound
by the unique binding, which
defines an entity with name in the same namespace as the
identifier, and
shadows all other bindings that define entities with name in that namespace.
It is an error if no such binding exists. If is bound by an
import clause, then the simple name is taken to be equivalent to
the qualified name to which is mapped by the import clause. If
is bound by a definition or declaration, then refers to the entity
introduced by that binding. In that case, the type of is the type
of the referenced entity.
Assume the following two definitions of a objects named in packages and .
package P
object X val x = 1; val y = 2
package Q
object X val x = true; val y = ""
The following program illustrates different kinds of bindings and
precedences between them.
package P // `X' bound by package clause
import Console._ // `println' bound by wildcard import
object A
println("L4: "+X) // `X' refers to `P.X' here
object B
import Q._ // `X' bound by wildcard import
println("L7: "+X) // `X' refers to `Q.X' here
import X._ // `x' and `y' bound by wildcard import
println("L8: "+x) // `x' refers to `Q.X.x' here
object C
val x = 3 // `x' bound by local definition
println("L12: "+x) // `x' refers to constant `3' here
import Q.X._ // `x' and `y' bound by wildcard import
// println("L14: "+x) // reference to `x' is ambiguous here
import X.y // `y' bound by explicit import
println("L16: "+y) // `y' refers to `Q.X.y' here
val x = "abc" // `x' bound by local definition
import P.X._ // `x' and `y' bound by wildcard import
// println("L19: "+y) // reference to `y' is ambiguous here
println("L20: "+x) // `x' refers to string ``abc'' here
A reference to a qualified (type- or term-) identifier refers to
the member of the type of which has the name in the same
namespace as the identifier. It is an error if is not a value type
(sec:value-types). The type of is the member type of the
referenced entity in .
Types
lstlisting
Type ::= FunctionArgTypes `=>' Type
InfixType [ExistentialClause]
FunctionArgTypes ::= InfixType
`(' [ ParamType `,' ParamType ] `)'
ExistentialClause ::= `forSome' `' ExistentialDcl semi ExistentialDcl `'
ExistentialDcl ::= `type' TypeDcl
`val' ValDcl
InfixType ::= CompoundType id [nl] CompoundType
CompoundType ::= AnnotType `with' AnnotType [Refinement]
Refinement
AnnotType ::= SimpleType Annotation
SimpleType ::= SimpleType TypeArgs
SimpleType `#' id
StableId
Path `.' `type'
`(' Types ')'
TypeArgs ::= `[' Types `]'
Types ::= Type `,' Type
We distinguish between first-order types and type constructors, which
take type parameters and yield types. A subset of first-order types
called value types represents sets of (first-class) values.
Value types are either concrete or abstract.
Every concrete value type can be represented as a class type, i.e. a
type designator (sec:type-desig) that refers to a
a class or a trait We assume that objects and packages also implicitly
define a class (of the same name as the object or package, but
inaccessible to user programs). (sec:class-defs), or as a
compound type (sec:compound-types) representing an
intersection of types, possibly with a refinement
(sec:refinements) that further constrains the types of its
members.
A shorthand exists for denoting function types (sec:function-types).
Abstract value types are introduced by type parameters (sec:type-params)
and abstract type bindings (sec:typedcl). Parentheses in types can be used for
grouping.
Non-value types capture properties of identifiers that are not values
(sec:synthetic-types). For example, a type constructor (sec:higherkinded-types) does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type.
Non-value types are expressed indirectly in Scala. E.g., a method type is described by writing down a method signature, which in itself is not a real type, although it gives rise to a corresponding method type (sec:method-types). Type constructors are another example, as one can write Swap[m[_, _], a,b] = m[b, a]@, but there is no syntax to write the corresponding anonymous type function directly.
Paths
lstlisting
Path ::= StableId
[id `.'] this
StableId ::= id
Path `.' id
[id '.'] `super' [ClassQualifier] `.' id
ClassQualifier ::= `[' id `]'
Paths are not types themselves, but they can be a part of named types
and in that function form a central role in Scala's type system.
A path is one of the following.
The empty path (which cannot be written explicitly in user programs).
.this@, where references a class.
The path this is taken as a shorthand for .this@ where
is the name of the class directly enclosing the reference.
.@ where is a path and is a stable member of .
Stable members are packages or members introduced by object definitions or
by value definitions of non-volatile types
(sec:volatile-types).
.super.@ or .super[].@
where references a class and references a
stable member of the super class or designated parent class of .
The prefix super is taken as a shorthand for .super@ where
is the name of the class directly enclosing the reference.
A stable identifier is a path which ends in an identifier.
Value Types
Every value in Scala has a type which is of one of the following
forms.
Singleton Types
lstlisting
SimpleType ::= Path `.' type
A singleton type is of the form .type@, where is a
path pointing to a value expected to conform (sec:expr-typing)
to .AnyRef@. The type denotes the set of values
consisting of null and the value denoted by .
A stable type is either a singleton type or a type which is
declared to be a subtype of trait .Singleton@.
Type Projection
lstlisting
SimpleType ::= SimpleType `#' id
A type projection #@ references the type member named
of type .
Type Designators
lstlisting
SimpleType ::= StableId
A type designator refers to a named value type. It can be simple or
qualified. All such type designators are shorthands for type projections.
Specifically, the unqualified type name where is bound in some
class, object, or package is taken as a shorthand for
.this.type#@. If is
not bound in a class, object, or package, then is taken as a
shorthand for .type#@.
A qualified type designator has the form .@ where is
a path (sec:paths) and is a type name. Such a type designator is
equivalent to the type projection .type#@.
Some type designators and their expansions are listed below. We assume
a local type parameter , a value maintable
with a type member Node and the standard class .Int@,
t .type#t
Int scala.type#Int
scala.Int scala.type#Int
data.maintable.Node data.maintable.type#Node
Parameterized Types
lstlisting
SimpleType ::= SimpleType TypeArgs
TypeArgs ::= `[' Types `]'
A parameterized type consists of a type
designator and type parameters where
. must refer to a type constructor which takes type
parameters .
Say the type parameters have lower bounds and
upper bounds . The parameterized type is
well-formed if each actual type parameter conforms to its
bounds, i.e. where is the
substitution .
ex:param-types
Given the partial type definitions:
class TreeMap[A <: Comparable[A], B]
class List[A]
class I extends Comparable[I]
class F[M[_], X]
class S[K <: String]
class G[M[ Z <: I ], I]
the following parameterized types are well formed:
TreeMap[I, String]
List[I]
List[List[Boolean]]
F[List, Int]
G[S, String]
Given the type definitions of ,
the following types are ill-formed:
TreeMap[I] // illegal: wrong number of parameters
TreeMap[List[I], Int] // illegal: type parameter not within bound
F[Int, Boolean] // illegal: Int is not a type constructor
F[TreeMap, Int] // illegal: TreeMap takes two parameters,
// F expects a constructor taking one
G[S, Int] // illegal: S constrains its parameter to
// conform to String,
// G expects type constructor with a parameter
// that conforms to Int
Tuple Types
lstlisting
SimpleType ::= `(' Types ')'
A tuple type ()@ is an alias for the
class .Tuple[]@, where
.
Tuple classes are case classes whose fields can be accessed using
selectors _1, ..., _@. Their functionality is
abstracted in a corresponding Product trait. The -ary tuple
class and product trait are defined at least as follows in the
standard Scala library (they might also add other methods and
implement other traits).
case class Tuple[+T1, ..., +T](_1: T1, ..., _: T)
extends Product[T1, ..., T]
trait Product[+T1, +T2, +T]
override def arity =
def _1: T1
...
def _:T
Annotated Types
lstlisting
AnnotType ::= SimpleType Annotation
An annotated type @
attaches annotations to the type
(sec:annotations).
The following type adds the @suspendable@ annotation to the type
String:
String @suspendable
Compound Types