• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1..
2    Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6    http://www.apache.org/licenses/LICENSE-2.0
7    Unless required by applicable law or agreed to in writing, software
8    distributed under the License is distributed on an "AS IS" BASIS,
9    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10    See the License for the specific language governing permissions and
11    limitations under the License.
12
13.. _Experimental Features:
14
15Experimental Features
16#####################
17
18.. meta:
19    frontend_status: Partly
20
21This Chapter introduces the |LANG| features that are considered parts of
22the language, but have no counterpart in |TS|, and are therefore not
23recommended to those in need of a single source code for |TS| and |LANG|.
24
25Some features introduced in this Chapter are still under discussion. They can
26be removed from the final version of the |LANG| specification. Once a feature
27introduced in this Chapter is approved and/or implemented, the corresponding
28section is moved to the body of the specification as appropriate.
29
30The *array creation* feature introduced in :ref:`Array Creation Expressions`
31enables users to dynamically create objects of array type by using runtime
32expressions that provide the array size. This is a useful addition to other
33array-related features of the language, such as array literals.
34
35The construct can also be used to create multidimensional arrays.
36
37The feature *function and method overloading* is supported in many
38(if not all) modern programming languages. Overloading functions/methods
39is a practical and convenient way to write program actions that are similar
40in logic but different in implementation.
41
42.. index::
43   implementation
44   array creation
45   runtime expression
46   array
47   array literal
48   construct
49   function overloading
50   method overloading
51
52The |LANG| language supports (as an experimental feature at the moment) two
53semantically and syntactically different implementations of overloading: the
54|TS|-like implementation, and that of other languages. See
55:ref:`Function and Method Overloading` for more details.
56
57Section :ref:`Native Functions and Methods` introduces practically important
58and useful mechanisms for the inclusion of components written in other languages
59into a program written in |LANG|.
60
61Section :ref:`Final Classes and Methods` discusses the well-known feature that
62in many OOP languages provides a way to restrict class inheritance and method
63overriding. Making a class *final* prohibits defining classes derived from it,
64whereas making a method *final* prevents it from overriding in derived classes.
65
66Section :ref:`Adding Functionality to Existing Types` defines the ability
67to add new functionality to already defined type. This
68feature can be used for GUI programming (:ref:`Support for GUI Programming`).
69
70Section :ref:`Enumeration Methods` adds methods to declarations of the
71enumeration types. Such methods can help in some kinds of manipulations
72with ``enums``.
73
74.. index::
75   implementation
76   function overloading
77   method overloading
78   final class
79   method final
80   OOP (object-oriented programming)
81   inheritance
82   enum
83   class
84   interface
85   inheritance
86   derived class
87
88Section :ref:`Exceptions` discusses the powerful, commonly used mechanism for
89the processing of various kinds of unexpected events and situations that break
90the *ordinary* program logic. There are constructs to raise (*throw*)
91exceptions, *catch* them along the dynamic sequence of function calls, and
92handle them. Some support for exceptions is also provided by the classes from
93the standard library (see :ref:`Standard Library`).
94
95**Note**: The exceptions mechanism is sometimes deprecated for being too
96time-consuming and unsafe. Some modern languages do not support the
97exceptions mechanism as discussed in this section. That is why the expediency
98of adding this feature to the language is still under discussion.
99
100The |LANG| language supports writing concurrent applications in the form of
101*coroutines* (see :ref:`Coroutines`) that allow executing functions
102concurrently, while the *channels* through which the coroutines can produce
103results are asynchronous.
104
105There is a basic set of language constructs that support concurrency. A function
106to be launched asynchronously is marked by adding the modifier ``async``
107to its declaration. In addition, any function---or lambda expression---can be
108launched as a separate thread explicitly by using the launch expression.
109
110.. index::
111   exception
112   construct
113   coroutine
114   channel
115   function
116   async modifier
117   launch expression
118   launch
119   lambda expression
120   concurrency
121   async modifier
122
123The ``await`` statement is introduced to synchronize functions launched as
124threads. The generic class ``Promise<T>`` from the standard library (see
125:ref:`Standard Library`) is used to exchange information between threads.
126The class can be handled as an implementation of the channel mechanism.
127The class provides a number of methods to manipulate the values produced
128by threads.
129
130Section :ref:`Packages` discusses a well-known and proven language feature
131intended to organize large pieces of software that typically consist of many
132components. *Packages* allow developers to construct a software product
133as a composition of subsystems, and organize the development process in a way
134that is appropriate for independent teams to work in parallel.
135
136.. index::
137   await statement
138   function
139   launch
140   generic class
141   standard library
142   implementation
143   channel
144   package
145   construct
146
147*Package* is the language construct that combines a number of declarations,
148and makes them parts of an independent compilation unit.
149
150The *export* and *import* features are used to organize communication between
151*packages*. An entity exported from one package becomes known to---and
152accessible (see :ref:`Accessible`) in---another package which imports that
153feature. Various options are provided to simplify export/import, e.g., by
154defining non-exported, i.e., ``internal`` declarations that are not accessible
155(see :ref:`Accessible`) from the outside of the package.
156
157In addition, |LANG| supports the *package* initialization semantics that
158makes a *package* even more independent from the environment.
159
160
161.. index::
162   package
163   construct
164   declaration
165   compilation unit
166   export
167   import
168   internal declaration
169   non-exported declaration
170   access
171   initialization
172   semantics
173
174|
175
176.. _Character Type and Literals:
177
178Character Type and Literals
179***************************
180
181|
182
183.. _Character Literals:
184
185Character Literals
186==================
187
188.. meta:
189    frontend_status: Done
190
191A ``char literal`` represents the following:
192
193-  A value with a single character; or
194-  A single escape sequence preceded by the characters *single quote* (U+0027)
195   and '*c*' (U+0063), and followed by a *single quote* U+0027).
196
197
198.. code-block:: abnf
199
200      CharLiteral:
201          'c\'' SingleQuoteCharacter '\''
202          ;
203
204      SingleQuoteCharacter:
205          ~['\\\r\n]
206          | '\\' EscapeSequence
207          ;
208
209The examples are presented below:
210
211.. code-block:: typescript
212   :linenos:
213
214      c'a'
215      c'\n'
216      c'\x7F'
217      c'\u0000'
218
219``Character Literals`` are of type ``char``.
220
221.. index::
222   char literal
223   character literal
224   escape sequence
225   single quote
226   type char
227
228|
229
230.. _Character Type and Operations:
231
232Character Type and Operations
233=============================
234
235.. meta:
236    frontend_status: Partly
237    todo: need to adapt the implementation to the latest specification
238
239+-----------+----------------------------------+------------------------------+
240| **Type**  | **Type's Set of Values**         | **Corresponding Class Type** |
241+===========+==================================+==============================+
242| ``char``  | Symbols with codes from \U+0000  | *Char*                       |
243|           | to \U+FFFF inclusive, that is,   |                              |
244|           | from *0* to *65,535*             |                              |
245+-----------+----------------------------------+------------------------------+
246
247|LANG| provides a number of operators to act on character values as discussed
248below.
249
250All character operators are identical to integer operators (see
251:ref:`Integer Types and Operations`) for they handle character values as
252integers of type ``int`` (see :ref:`Widening Primitive Conversions`).
253
254The class ``Char`` provides constructors, methods, and constants that are
255parts of the |LANG| standard library (see :ref:`Standard Library`).
256
257.. index::
258   char
259   Char
260   boolean
261   equality operator
262   constructor
263   method
264   constant
265
266|
267
268.. _Array Creation Expressions:
269
270Array Creation Expressions
271**************************
272
273.. meta:
274    frontend_status: Done
275
276An *array creation expression* creates new objects that are instances of arrays.
277The *array literal* expression is used to create an array instance, and to
278provide some initial values (see :ref:`Array Literal`).
279
280.. code-block:: abnf
281
282      newArrayInstance:
283          'new' arrayElementType dimensionExpression+ (arrayElement)?
284          ;
285
286      arrayElementType:
287          typeReference
288          | '(' type ')'
289          ;
290
291      dimensionExpression:
292          '[' expression ']'
293          ;
294
295      arrayElement:
296          '(' expression ')'
297          ;
298
299.. code-block:: typescript
300   :linenos:
301
302      let x = new number[2][2] // create 2x2 matrix
303
304An *array creation expression* creates an object that is a new array with the
305elements of the type specified by ``arrayElelementType``.
306
307The type of each *dimensionExpression* must be convertible (see
308:ref:`Primitive Types Conversions`) to an integer type. Otherwise,
309a :index:`compile-time error` occurs.
310
311A numeric conversion (see :ref:`Primitive Types Conversions`) is performed
312on each *dimensionExpression* to ensure that the resultant type is ``int``.
313Otherwise, a :index:`compile-time error` occurs.
314
315A :index:`compile-time error` occurs if any *dimensionExpression* is a
316constant expression that is evaluated at compile time to a negative integer
317value.
318
319.. index::
320   array creation expression
321   conversion
322   integer
323   type
324   value
325   numeric conversion
326   type int
327   constant expression
328
329If the type of any *dimensionExpression* is ``number`` or other floating-point
330type, and its fractional part is different from '0', then errors occur as
331follows:
332
333- A runtime error, if the situation is identified during program execution; and
334- A :index:`compile-time error`, if the situation is detected during
335  compilation.
336
337If ``arrayElement`` is provided, then the type of the ``expression`` can be
338as follows:
339
340- Type of array element denoted by ``arrayElelementType``, or
341- Lambda function with the return type equal to the type of array element
342  denoted by ``arrayElelementType`` and the parameters of type ``int``, and the
343  number of parameters equal to the number of array dimensions.
344
345.. index::
346   type
347   floating-point type
348   runtime error
349   compilation
350   expression
351   lambda function
352   array
353   parameter
354   array
355
356Otherwise, a :index:`compile-time error` occurs.
357
358.. code-block:: typescript
359   :linenos:
360
361      let x = new number[-3] // compile-time error
362
363      let y = new number[3.141592653589]  // compile-time error
364
365      foo (3.141592653589)
366      function foo (size: number) {
367         let y = new number[size]  // runtime error
368      }
369
370
371A :index:`compile-time error` occurs if ``arrayElelementType`` refers to a
372class that does not contain an accessible (see :ref:`Accessible`) parameterless
373constructor, or constructor with all parameters of the second form of optional
374parameters (see :ref:`Optional Parameters`), or if ``type`` has no default
375value:
376
377.. code-block-meta:
378   expect-cte:
379
380.. code-block:: typescript
381   :linenos:
382
383      let x = new string[3] // compile-time error: string has no default value
384
385      class A {
386         constructor (p1?: number, p2?: string) {}
387      }
388      let y = new A[2] // OK, as all 3 elements of array will be filled with
389      // new A() objects
390
391A :index:`compile-time error` occurs if ``arrayElelementType`` is a type
392parameter:
393
394.. code-block:: typescript
395   :linenos:
396
397      class A<T> {
398         foo() {
399            new T[2] // compile-time error: cannot create an array of type parameter elements
400         }
401      }
402
403.. index::
404   accessibility
405   constructor
406   array
407
408Creating an array with a known number of elements is presented below:
409
410.. code-block:: typescript
411   :linenos:
412
413      class A {}
414         // It has no default value or parameterless constructor defined
415
416      let array_size = 5
417
418      let array1 = new A[array_size] (new A)
419         /* Create array of 'array_size' elements and all of them will have
420            initial value equal to an object created by new A expression */
421
422      let array2 = new A[array_size] ((index): A => { return new A })
423         /* Create array of `array_size` elements and all of them will have
424            initial value equal to the result of lambda function execution with
425            different indices */
426
427      let array2 = new A[2][3] ((index1, index2): A => { return new A })
428         /* Create two-dimensional array of 6 elements total and all of them will
429            have initial value equal to the result of lambda function execution with
430            different indices */
431
432Creating exotic arrays with different kinds of element types is presented below:
433
434.. code-block:: typescript
435   :linenos:
436
437      let array_of_union = new (Object|null) [5] // filled with null
438      let array_of_functor = new (() => void) [5] ( (): void => {})
439      type aliasTypeName = number []
440      let array_of_array = new aliasTypeName [5] ( [3.141592653589] )
441
442|
443
444.. _Runtime Evaluation of Array Creation Expressions:
445
446Runtime Evaluation of Array Creation Expressions
447================================================
448
449.. meta:
450    frontend_status: Partly
451    todo: initialize array elements properly - #14963, #15610
452
453The evaluation of an array creation expression at runtime is performed
454as follows:
455
456#. The dimension expressions are evaluated. The evaluation is performed
457   left-to-right; if any expression evaluation completes abruptly, then
458   the expressions to the right of it are not evaluated.
459
460#. The values of dimension expressions are checked. If the value of any
461   ``dimExpr`` expression is less than zero, then ``NegativeArraySizeError`` is
462   thrown.
463
464#. Space for the new array is allocated. If the available space is not
465   sufficient to allocate the array, then ``OutOfMemoryError`` is thrown,
466   and the evaluation of the array creation expression completes abruptly.
467
468#. When a one-dimensional array is created, each element of that array
469   is initialized to its default value if type default value is defined
470   (:ref:`Default Values for Types`).
471   If the default value for an element type is not defined, but the element
472   type is a class type, then its *parameterless* constructor is used to
473   create the value of each element.
474
475#. When a multidimensional array is created, the array creation effectively
476   executes a set of nested loops of depth *n-1*, and creates an implied
477   array of arrays.
478
479.. index::
480   array
481   constructor
482   abrupt completion
483   expression
484   runtime
485   evaluation
486   default value
487   parameterless constructor
488   class type
489   initialization
490   nested loop
491
492|
493
494.. _Indexable Types:
495
496Indexable Types
497***************
498
499.. meta:
500    frontend_status: Done
501
502If a class or an interface declares one or two functions with names ``$_get``
503and ``$_set``, and signatures *(index: Type1): Type2* and *(index: Type1,
504value: Type2)* respectively, then an indexing expression (see
505:ref:`Indexing Expressions`) can be applied to variables of such types:
506
507.. code-block-meta:
508
509.. code-block:: typescript
510   :linenos:
511
512    class SomeClass {
513       $_get (index: number): SomeClass { return this }
514       $_set (index: number, value: SomeClass) { }
515    }
516    let x = new SomeClass
517    x = x[1] // This notation implies a call: x = x.$_get (1)
518    x[1] = x // This notation implies a call: x.$_set (1, x)
519
520If only one function is present, then only the appropriate form of the index
521expressions (see :ref:`Indexing Expressions`) is available:
522
523.. code-block-meta:
524   expect-cte:
525
526.. code-block:: typescript
527   :linenos:
528
529    class ClassWithGet {
530       $_get (index: number): ClassWithGet { return this }
531    }
532    let getClass = new ClassWithGet
533    getClass = getClass[0]
534    getClass[0] = getClass // Error - no $_set function available
535
536    class ClassWithSet {
537       $_set (index: number, value: ClassWithSet) { }
538    }
539    let setClass = new ClassWithSet
540    setClass = setClass[0] // Error - no $_get function available
541    setClass[0] = setClass
542
543
544.. index::
545   function
546   signature
547   indexing expression
548   variable
549   index expression
550   string
551
552Type ``string`` can be used as a type of the index parameter:
553
554.. code-block-meta:
555
556.. code-block:: typescript
557   :linenos:
558
559    class SomeClass {
560       $_get (index: string): SomeClass { return this }
561       $_set (index: string, value: SomeClass) { }
562    }
563    let x = new SomeClass
564    x = x["index string"]
565       // This notation implies a call: x = x.$_get ("index string")
566    x["index string"] = x
567       // This notation implies a call: x.$_set ("index string", x)
568
569Functions ``$_get`` and ``$_set`` are ordinary functions with compiler-known
570signatures. The functions can be used like any other function.
571The functions can be abstract, or defined in an interface and implemented later.
572The functions can be overridden and provide a dynamic dispatch for the indexing
573expression evaluation (see :ref:`Indexing Expressions`). The functions can be
574used in generic classes and interfaces for better flexibility. A
575:index:`compile-time error` occurs if these functions are marked as ``async``.
576
577.. index::
578   index parameter
579   function
580   compiler
581   signature
582   overriding
583   interface
584   implementation
585   indexing expression
586   evaluation
587   flexibility
588   async function
589   generic class
590
591.. code-block-meta:
592   expect-cte:
593
594.. code-block:: typescript
595   :linenos:
596
597    interface ReadonlyIndexable<K, V> {
598       $_get (index: K): V
599    }
600
601    interface Indexable<K, V> extends ReadonlyIndexable<K, V> {
602       $_set (index: K, value: V)
603    }
604
605    class IndexableByNumber<V> extends Indexable<number, V> {
606       private data: V[] = []
607       $_get (index: number): V { return this.data [index] }
608       $_set (index: number, value: V) { this.data[index] = value }
609    }
610
611    class IndexableByString<V> extends Indexable<string, V> {
612       private data = new Map<string, V>
613       $_get (index: string): V { return this.data [index] }
614       $_set (index: string, value: V) { this.data[index] = value }
615    }
616
617    class BadClass extends IndexableByNumber<boolean> {
618       override $_set (index: number, value: boolean) { index / 0 }
619    }
620
621    let x: IndexableByNumber<boolean> = new BadClass
622    x[666] = true // This will be dispatched at runtime to the overridden
623       // version of the $_set method
624    x.$_get (15)  // $_get and $_set can be called as ordinary
625       // methods
626
627|
628
629.. _Iterable Types:
630
631Iterable Types
632**************
633
634.. meta:
635    frontend_status: Done
636
637A class or an interface can be made *iterable*, meaning that their instances
638can be used in ``for-of`` statements (see :ref:`For-Of Statements`).
639
640Some type ``C`` is *iterable* if it declares a parameterless function with name
641``$_iterator`` with the return type which is compatible (see
642:ref:`Type Compatibility`) with type ``Iterator``, defined in the standard
643library (see :ref:`Standard Library`). It guarantees the object returned
644is of the class type which implements ``Iterator``, and thus allows traversing
645an object of class type ``C``. The example below defines *iterable* class ``C``:
646
647.. index::
648   iterable type
649   class
650   interface
651   instance
652   for-of statement
653   parameterless function
654   compatibility
655   iterable class
656
657.. code-block:: typescript
658   :linenos:
659
660      class C {
661        data: string[] = ['a', 'b', 'c']
662        $_iterator() { // Function type is inferred from its body
663          return new CIterator(this)
664        }
665      }
666
667      class CIterator implements Iterator<string> {
668        index = 0
669        base: C
670        constructor (base: C) {
671          this.base = base
672        }
673        next(): IteratorResult<string> {
674          return {
675            done: this.index >= this.base.data.length,
676            value: this.index >= this.base.data.length ? undefined : this.base.data[this.index++]
677          }
678        }
679      }
680
681      let c = new C()
682      for (let x of c) {
683            console.log(x)
684      }
685
686In the example above, class ``C`` function ``$_iterator`` returns
687``CIterator<string>`` that implements ``Iterator<string>``. If executed,
688this code prints out the following:
689
690.. code-block:: typescript
691
692    "a"
693    "b"
694    "c"
695
696
697The function ``$_iterator`` is an ordinary function with a compiler-known
698signature. The function can be used like any other function. It can be
699abstract or defined in an interface to be implemented later. A
700:index:`compile-time error` occurs if this function is marked as ``async``.
701
702.. index::
703   function
704   class
705   string
706   iterator
707   compiler
708   signature
709   async function
710
711**Note**: To support the code compatible with |TS|, the name of the function
712``$_iterator`` can be written as ``[Symbol.iterator]``. In this case, the class
713``iterable`` looks as follows:
714
715.. code-block-meta:
716
717.. code-block:: typescript
718   :linenos:
719
720      class C {
721        data: string[] = ['a', 'b', 'c'];
722        [Symbol.iterator]() {
723          return new CIterator(this)
724        }
725      }
726
727The use of the name ``[Symbol.iterator]`` is considered deprecated.
728It can be removed in the future versions of the language.
729
730.. index::
731   compatibility
732   function
733   iterator
734   class
735
736|
737
738.. _Callable Types:
739
740Callable Types
741**************
742
743.. meta:
744    frontend_status: Done
745
746A type is *callable* if the name of the type can be used in a call expression.
747A call expression that uses the name of a type is called a *type call
748expression*. Only class type can be callable. To make a type
749callable, a static method with the name ``invoke`` or ``instantiate`` must be
750defined or inherited:
751
752.. code-block-meta:
753
754.. code-block:: typescript
755   :linenos:
756
757    class C {
758        static invoke() { console.log("invoked") }
759    }
760    C() // prints: invoked
761    C.invoke() // also prints: invoked
762
763In the above example, ``C()`` is a *type call expression*. It is the short
764form of the normal method call ``C.invoke()``. Using an explicit call is always
765valid for the methods ``invoke`` and ``instantiate``.
766
767.. index::
768   callable type
769   call expression
770   expression
771   type call expression
772   class type
773   method call
774   instantiation
775
776**Note**: Only a constructor---not the methods ``invoke`` or ``instantiate``---is
777called in a *new expression*:
778
779.. code-block-meta:
780
781.. code-block:: typescript
782   :linenos:
783
784    class C {
785        static invoke() { console.log("invoked") }
786        constructor() { console.log("constructed") }
787    }
788    let x = new C() // constructor is called
789
790The methods ``invoke`` and ``instantiate`` are similar but have differences as
791discussed below.
792
793A :index:`compile-time error` occurs if a callable type contains both methods
794``invoke`` and ``instantiate``.
795
796.. index::
797   method
798   instantiation
799
800|
801
802.. _Callable Types with Invoke Method:
803
804Callable Types with Invoke Method
805=================================
806
807.. meta:
808    frontend_status: Done
809
810The method ``invoke`` can have an arbitrary signature. The method can be used
811in a *type call expression* in either case above. If the signature has
812parameters, then the call must contain corresponding arguments.
813
814.. code-block-meta:
815
816.. code-block:: typescript
817   :linenos:
818
819    class Add {
820        static invoke(a: number, b: number): number {
821            return a + b
822        }
823    }
824    console.log(Add(2, 2)) // prints: 4
825
826.. index::
827   callable type
828   signature
829   method
830   type call expression
831   argument
832
833|
834
835.. _Callable Types with Instantiate Method:
836
837Callable Types with Instantiate Method
838======================================
839
840.. meta:
841    frontend_status: Partly
842    todo: es2panda segfaults on the first example
843
844The method ``instantiate`` can have an arbitrary signature by itself.
845If it is to be used in a *type call expression*, then its first parameter
846must be a ``factory`` (i.e., it must be a *parameterless function type
847returning some class or struct type*).
848The method can have or not have other parameters, and those parameters can
849be arbitrary.
850
851In a *type call expression*, the argument corresponding to the ``factory``
852parameter is passed implicitly:
853
854.. code-block:: typescript
855   :linenos:
856
857    class C {
858        static instantiate(factory: () => C): C {
859            return factory()
860        }
861    }
862    let x = C() // factory is passed implicitly
863
864    // Explicit call of 'instantiate' requires explicit 'factory':
865    let y = C.instantiate(() => { return new C()})
866
867.. index::
868   method
869   signature
870   type call expression
871   factory
872   parameterless function type
873   struct type
874
875If the method ``instantiate`` has additional parameters, then the call must
876contain corresponding arguments:
877
878.. code-block:: typescript
879   :linenos:
880
881    class C {
882        name = ""
883        static instantiate(factory: () => C, name: string): C {
884            let x = factory()
885            x.name = name
886            return x
887        }
888    }
889    let x = C("Bob") // factory is passed implicitly
890
891A :index:`compile-time error` occurs in a *type call expression* with type ``T``,
892if:
893
894- ``T`` has neither method ``invoke`` nor  method ``instantiate``; or
895- ``T`` has the method ``instantiate`` but its first parameter is not
896  a ``factory``.
897
898.. index::
899   type call expression
900   instantiation
901   method
902   parameter
903
904.. code-block-meta:
905    expect-cte
906
907.. code-block:: typescript
908   :linenos:
909
910    class C {
911        static instantiate(factory: string): C {
912            return factory()
913        }
914    }
915    let x = C() // compile-time error, wrong 'instantiate' 1st parameter
916
917|
918
919.. _Statements Experimental:
920
921Statements
922**********
923
924.. meta:
925    frontend_status: Done
926
927|
928
929
930.. _For-of Type Annotation:
931
932For-of Type Annotation
933======================
934
935.. meta:
936    frontend_status: Done
937
938An explicit type annotation is allowed for a *for-variable*:
939
940.. code-block:: typescript
941   :linenos:
942
943      // explicit type is used for a new variable,
944      let x: number[] = [1, 2, 3]
945      for (let n: number of x) {
946        console.log(n)
947      }
948
949.. index::
950   type annotation
951   for-variable
952   for-of type annotation
953
954|
955
956.. _Multiple Catch Clauses in Try Statements:
957
958Multiple Catch Clauses in Try Statements
959========================================
960
961.. meta:
962    frontend_status: Done
963
964When an exception or an error is thrown in the ``try`` block
965(see :ref:`try Statements`), or in a
966*throwing* or *rethrowing* function (see :ref:`Throwing Functions` and
967:ref:`Rethrowing Functions`) called from the ``try`` block, the control is
968transferred to the first ``catch`` clause if the statement has at least one
969``catch`` clause that can catch that exception or error. If no ``catch``
970clause is found, then exception or error is propagated to the surrounding
971scope.
972
973**Note**: An exception handled within a *non-throwing* function (see
974:ref:`Non-Throwing Functions`) is never propagated outside that function.
975
976A ``catch`` clause has two parts:
977
978-  Exception parameter that provides access to the object associated
979   with the exception or the error occurred; and
980
981-  Block of code that is to handle the situation.
982
983.. index::
984   exception
985   error
986   throwing function
987   rethrowing function
988   non-throwing function
989   try block
990   try statement
991   propagation
992   scope
993   catch clause
994   propagation
995   exception parameter
996   access
997
998*Default catch clause* is a ``catch`` clause with the exception parameter type
999omitted. Such a ``catch`` clause handles any exception or error that is not
1000handled by any previous clause. The type of that parameter is union
1001``Exception`` | ``Error``.
1002
1003A :index:`compile-time error` occurs if:
1004
1005-  Default ``catch`` clause is not the last ``catch`` clause in a
1006   ``try`` statement.
1007
1008-  Type reference of an exception parameter (if any) is neither the
1009   class ``Exception`` or ``Error``, nor a class derived from ``Exception`` or
1010   ``Error``.
1011
1012.. index::
1013   catch clause
1014   default catch clause
1015   exception
1016   parameter type
1017   union
1018   try statement
1019   type reference
1020   error
1021
1022.. code-block-meta:
1023
1024.. code-block:: typescript
1025   :linenos:
1026
1027      class ZeroDivisorException extends Exception {}
1028
1029      function divide(a: int, b: int): int throws {
1030        if (b == 0) throw new ZeroDivisorException()
1031        return a / b
1032      }
1033
1034      function process(a: int; b: int) {
1035        try {
1036          let res = divide(a, b)
1037
1038          // Division successful, further processing ...
1039        }
1040        catch (d: ZeroDivisorException) {
1041          // Handle zero division situation
1042        }
1043        catch (e) { // type of 'e' is Error|Exception
1044          // Handle all other errors or exceptions
1045        }
1046      }
1047
1048
1049All exceptions that the ``try`` block can throw are caught by the function
1050*process*. Special handling is provided for the ``ZeroDivisor`` exception,
1051and the handling of other exceptions and errors is different.
1052
1053``Catch`` clauses do not handle every possible exception or error that can
1054be thrown by the code in the ``try`` block. If no ``catch`` clause can handle
1055the situation, then exception or error is propagated to the surrounding scope.
1056
1057**Note**: If a ``try`` statement (*default catch clause*) is placed inside a
1058*non-throwing* function (see :ref:`Non-Throwing Functions`), then exception
1059is never propagated.
1060
1061.. index::
1062   exception
1063   try block
1064   exception
1065   propagation
1066   try statement
1067   default catch clause
1068   non-throwing function
1069
1070If a ``catch`` clause contains a block that corresponds to a parameter of the
1071error, then it can only handle that error.
1072
1073The type of the ``catch`` clause parameter in a *default catch clause* is
1074omitted. The ``catch`` clause can handle any exceptions or errors unhandled
1075by the previous clauses.
1076
1077The type of a ``catch`` clause parameter (if any) must be of the class
1078``Error`` or ``Exception``, or of another class derived from ``Exception``
1079or ``Error``.
1080
1081.. index::
1082   exception
1083   error
1084   catch clause
1085   default catch clause
1086   derived class
1087   Error
1088   Exception
1089
1090.. code-block:: typescript
1091   :linenos:
1092
1093        function process(a: int; b: int): int {
1094        try {
1095          return a / b
1096        }
1097        catch (x: DivideByZeroError) { return MaxInt }
1098      }
1099
1100A ``catch`` clause handles the ``DivideByZeroError`` at runtime. Other errors
1101are propagated to the surrounding scope if no ``catch`` clause is found.
1102
1103.. index::
1104   catch clause
1105   runtime
1106   error
1107   propagation
1108   scope
1109
1110|
1111
1112.. _Function and Method Overloading:
1113
1114Function and Method Overloading
1115*******************************
1116
1117.. meta:
1118    frontend_status: Done
1119
1120Similarly to |TS|, the |LANG| language supports overload signatures that allow
1121specifying several headers for a function or method with different signatures.
1122Most other languages support a different form of overloading that specifies
1123a separate body for each overloaded header.
1124
1125Both approaches have their advantages and disadvantages. The latter approach
1126supported by |LANG| can deliver better performance because no extra checks
1127are performed during the execution of a specific body at runtime.
1128
1129.. index::
1130   function overloading
1131   method overloading
1132   overload signature
1133   header
1134   function
1135   method
1136   signature
1137   overloaded header
1138   runtime
1139
1140|
1141
1142.. _Function Overloading:
1143
1144Function Overloading
1145====================
1146
1147.. meta:
1148    frontend_status: Done
1149
1150If a declaration scope declares and/or imports two or more functions with the
1151same name but different signatures that are not *overload-equivalent* (see
1152:ref:`Overload-Equivalent Signatures`), then such functions are *overloaded*.
1153Function overloading declarations cause no :index:`compile-time error` on their
1154own.
1155
1156No specific relationship is required between the return types, or between the
1157``throws`` clauses of the two functions with the same name but different
1158signatures that are not *overload-equivalent* (see
1159:ref:`Overload-Equivalent Signatures`).
1160
1161When calling an overloaded function, the number of actual arguments (and any
1162explicit type arguments) and compile-time argument types are used at compile
1163time to determine exactly which one is to be called (see
1164:ref:`Function Call Expression`).
1165
1166.. index::
1167   function overloading
1168   declaration scope
1169   signature
1170   name
1171   overload-equivalence
1172   overload-equivalent signature
1173   overloaded function name
1174   return type
1175   throws clause
1176   argument
1177   type argument
1178   function call
1179   compile-time error
1180
1181|
1182
1183.. _Class Method Overloading:
1184
1185Class Method Overloading
1186========================
1187
1188.. meta:
1189    frontend_status: Done
1190
1191If two or more methods within a class have the same name, and their signatures
1192are not *overload-equivalent* (see :ref:`Overload-Equivalent Signatures`), then
1193such methods are considered *overloaded*.
1194
1195Method overloading declarations cause no :index:`compile-time error` on their
1196own, except where a possible instantiation causes an *overload-equivalent* (see
1197:ref:`Overload-Equivalent Signatures`) method in the instantiated class or
1198interface:
1199
1200.. index::
1201   class method overloading
1202   class
1203   signature
1204   overload-equivalent signature
1205   overload equivalence
1206   overloading
1207   method
1208   instantiation
1209   interface
1210
1211.. code-block:: typescript
1212   :linenos:
1213
1214     class Template<T> {
1215        foo (p: number) { ... }
1216        foo (p: T) { ... }
1217     }
1218     let instantiation: Template<number>
1219       // Leads to two *overload-equivalent* methods
1220
1221     interface ITemplate<T> {
1222        foo (p: number)
1223        foo (p: T)
1224     }
1225     function foo (instantiation: ITemplate<number>) { ... }
1226       // Leads to two *overload-equivalent* methods
1227
1228
1229
1230If the signatures of two or more methods with the same name are not
1231*overload-equivalent* (see :ref:`Overload-Equivalent Signatures`), then the
1232return types of those methods, or the ``throws`` or ``rethrows`` clauses of
1233those methods can have any kind of relationship.
1234
1235When calling an overloaded method, the number of actual arguments (and any
1236explicit type arguments) and compile-time argument types are used at compile
1237time to determine exactly which one is to be called (see
1238:ref:`Method Call Expression`, and :ref:`Step 2 Selection of Method`).
1239
1240.. index::
1241   signature
1242   overload-equivalent signature
1243   overload equivalence
1244   throws clause
1245   rethrows clause
1246   type argument
1247   argument type
1248   method call
1249   instance method
1250
1251|
1252
1253.. _Constructor Overloading:
1254
1255Constructor Overloading
1256=======================
1257
1258.. meta:
1259    frontend_status: Done
1260
1261Constructor overloading behavior is identical to that of method overloading (see
1262:ref:`Class Method Overloading`). Each class instance creation expression (see
1263:ref:`New Expressions`) resolves the constructor overloading call if any at
1264compile time.
1265
1266.. index::
1267   constructor overloading
1268   method overloading
1269   class instance
1270   creation expression
1271   compile time
1272
1273|
1274
1275.. _Declaration Distinguishable by Signatures:
1276
1277Declaration Distinguishable by Signatures
1278=========================================
1279
1280.. meta:
1281    frontend_status: Done
1282
1283Same-name declarations are distinguishable by signatures if such
1284declarations are one of the following:
1285
1286-  Functions with the same name and signatures that are not
1287   *overload-equivalent* (see :ref:`Overload-Equivalent Signatures` and
1288   :ref:`Function Overloading`).
1289
1290-  Methods with the same name and signatures that are not
1291   *overload-equivalent* (see :ref:`Overload-Equivalent Signatures`,
1292   :ref:`Class Method Overloading`, and :ref:`Interface Method Overloading`).
1293
1294-  Constructors of the same class and signatures that are not
1295   *overload-equivalent* (see :ref:`Overload-Equivalent Signatures` and
1296   :ref:`Constructor Overloading`).
1297
1298.. index::
1299   distinguishable declaration
1300   signature
1301   function
1302   overloading
1303   overload-equivalent signature
1304   overload-equivalence
1305   constructor
1306
1307The example below represents the functions distinguishable by signatures:
1308
1309.. code-block:: typescript
1310   :linenos:
1311
1312      function foo() {}
1313      function foo(x: number) {}
1314      function foo(x: number[]) {}
1315      function foo(x: string) {}
1316
1317The following example represents the functions undistinguishable by signatures
1318that cause a :index:`compile-time error`:
1319
1320.. code-block:: typescript
1321   :linenos:
1322
1323      // Functions have overload-equivalent signatures
1324      function foo(x: number) {}
1325      function foo(y: number) {}
1326
1327      // Functions have overload-equivalent signatures
1328      function foo(x: number) {}
1329      type MyNumber = number
1330      function foo(x: MyNumber) {}
1331
1332.. index::
1333   distinguishable function
1334   function
1335   signature
1336
1337|
1338
1339|
1340
1341.. _Native Functions and Methods:
1342
1343Native Functions and Methods
1344****************************
1345
1346.. meta:
1347    frontend_status: Done
1348
1349|
1350
1351.. _Native Functions:
1352
1353Native Functions
1354================
1355
1356.. meta:
1357    frontend_status: Done
1358
1359A native function is a function that marked with ``native`` keyword (see :ref:`Function Declarations`).
1360
1361A ``native`` function implemented in a platform-dependent code is typically
1362written in another programming language (e.g., *C*). A :index:`compile-time error`
1363occurs if a ``native`` function has a body.
1364
1365.. index::
1366   keyword native
1367   function
1368   native function
1369   implementation
1370   platform-dependent code
1371   compile-time error
1372   function body
1373
1374|
1375
1376.. _Native Methods Experimental:
1377
1378Native Methods
1379==============
1380
1381.. meta:
1382    frontend_status: Done
1383
1384A native method is a method that marked with ``native`` keyword (see :ref:`Method Declarations`).
1385
1386``Native`` methods are the methods implemented in a platform-dependent code
1387written in another programming language (e.g., *C*).
1388
1389A :index:`compile-time error` occurs if:
1390
1391-  The method declaration contains the keyword ``abstract`` along with the
1392   keyword ``native``.
1393
1394-  The ``native`` method has a body (see :ref:`Method Body`) that is a block
1395   instead of a simple semicolon or empty body.
1396
1397.. index::
1398   native method
1399   implementation
1400   platform-dependent code
1401   keyword native
1402   method body
1403   block
1404   method declaration
1405   keyword abstract
1406   semicolon
1407   empty body
1408
1409|
1410
1411.. _Native Constructors:
1412
1413Native Constructors
1414===================
1415
1416.. meta:
1417    frontend_status: None
1418
1419A native constructor is a constructor that marked with ``native`` keyword (see :ref:`Constructor Declaration`).
1420
1421``Native`` constructors are the constructors implemented in a platform-dependent code
1422written in another programming language (e.g., *C*).
1423
1424A :index:`compile-time error` occurs if:
1425
1426-  The ``native`` constructor has a non-empty body (see :ref:`Constructor Body`).
1427
1428.. index::
1429   native constructor
1430   platform-dependent code
1431   keyword native
1432   non-empty body
1433
1434|
1435
1436.. _Final Classes and Methods:
1437
1438Final Classes and Methods
1439*************************
1440
1441.. meta:
1442    frontend_status: Done
1443
1444|
1445
1446.. _Final Classes Experimental:
1447
1448Final Classes
1449=============
1450
1451.. meta:
1452    frontend_status: Done
1453
1454A class can be declared ``final`` to prevent extension, i.e., a class declared
1455``final`` cannot have subclasses. No method of a ``final`` class can be
1456overridden.
1457
1458If a class type ``F`` expression is declared *final*, then only a class ``F``
1459object can be its value.
1460
1461A :index:`compile-time error` occurs if the ``extends`` clause of a class
1462declaration contains another class that is ``final``.
1463
1464.. index::
1465   final class
1466   method
1467   overriding
1468   class
1469   class extension
1470   extends clause
1471   class declaration
1472   subclass
1473
1474|
1475
1476.. _Final Methods Experimental:
1477
1478Final Methods
1479=============
1480
1481.. meta:
1482    frontend_status: Done
1483
1484A method can be declared ``final`` to prevent it from being overridden (see
1485:ref:`Overloading and Overriding`) in subclasses.
1486
1487A :index:`compile-time error` occurs if:
1488
1489-  The method declaration contains the keyword ``abstract`` or ``static``
1490   along with the keyword ``final``.
1491
1492-  A method declared ``final`` is overridden.
1493
1494.. index::
1495   final method
1496   overriding
1497   instance method
1498   subclass
1499   method declaration
1500   keyword abstract
1501   keyword static
1502   keyword final
1503
1504|
1505
1506.. _Default Interface Method Declarations:
1507
1508Default Interface Method Declarations
1509*************************************
1510
1511.. meta:
1512    frontend_status: Done
1513
1514.. code-block:: abnf
1515
1516    interfaceDefaultMethodDeclaration:
1517        'private'? identifier signature block
1518        ;
1519
1520A default method can be explicitly declared ``private`` in an interface body.
1521
1522A block of code that represents the body of a default method in an interface
1523provides a default implementation for any class if such class does not override
1524the method that implements the interface.
1525
1526.. index::
1527   default method
1528   method declaration
1529   private
1530   implementation
1531   default method body
1532   interface body
1533   default implementation
1534   overriding
1535
1536|
1537
1538.. _Adding Functionality to Existing Types:
1539
1540Adding Functionality to Existing Types
1541**************************************
1542
1543|LANG| supports adding functions and accessors to already defined types,
1544so its usage looks the same, as if they are methods and accessors of these types.
1545The mechanism used is called: :ref:`Functions with Receiver` and
1546:ref:`Accessors with Receiver`. This feature is often used to add new
1547functionality to a class without having to inherit from this class.
1548However, it can be used not only for classes but for other types as well.
1549
1550Additionally, :ref:`Function Types with Receiver` and
1551:ref:`Lambda Expressions with Receiver` can be defined and use,
1552making the code more flexible.
1553
1554.. _Functions with Receiver:
1555
1556Functions with Receiver
1557=======================
1558
1559.. meta:
1560    frontend_status: None
1561    todo: import/export of them, function with receiver of primitive types or array
1562
1563A *function with receiver* declaration is a top-level declaration
1564(see :ref:`Top-Level Declarations`) that looks almost the same as
1565:ref:`Function Declarations`, except that the first parameter is mandatory,
1566and keyword ``this`` is used as its name:
1567
1568.. code-block:: abnf
1569
1570    functionWithReceiverDeclaration:
1571        'function' identifier typeParameters? signatureWithReceiver block
1572        ;
1573
1574    signatureWithReceiver:
1575        '(' receiverParameter (', ' parameterList)? ')' returnType? throwMark?
1576        ;
1577
1578    receiverParameter:
1579        'this' ':' 'readonly'? type
1580        ;
1581
1582There are two ways to call a *function with receiver*:
1583
1584-  as a function call (see :ref:`Function Call Expression`),
1585   passing the first parameter in the usual way
1586
1587-  as a method call (see :ref:`Method Call Expression`), where
1588   no argument is provided for the first parameter
1589   and the ``objectReference`` before
1590   the function name is used as the first argument
1591
1592.. code-block:: typescript
1593   :linenos:
1594
1595      class C {}
1596
1597      function foo(this: C) {}
1598      function bar(this: C, n: number): void {}
1599
1600      let c = new C()
1601
1602      // as a function call:
1603      foo(c)
1604      bar(c, 1)
1605
1606      // as a method call:
1607      c.foo()
1608      c.bar(1)
1609
1610The keyword ``this`` can be used inside a *function with receiver*
1611and it corresponds the first parameter.
1612
1613The type of ``this`` parameter is called the *receiver type*
1614(see :ref:`Receiver Type`).
1615
1616
1617If the *receiver type* is a class type, ``private`` or ``protected``
1618members are not accessible (see :ref:`Accessible`) within the bodies of thee
1619*function with receiver*. Only ``public`` members can be accessed:
1620
1621.. index::
1622   keyword this
1623   private
1624   protected
1625   access
1626
1627.. code-block:: typescript
1628   :linenos:
1629
1630      class A {
1631          foo () { ... this.bar() ... }
1632                       // function bar() is accessible here
1633          protected member_1 ...
1634          private member_2 ...
1635      }
1636      function bar(this: A) { ...
1637         this.foo() // Method foo() is accessible as it is public
1638         this.member_1 // Compile-time error as member_1 is not accessible
1639         this.member_2 // Compile-time error as member_2 is not accessible
1640         ...
1641      }
1642      let a = new A()
1643      a.foo() // Ordinary class method is called
1644      a.bar() // Function with receiver is called
1645
1646The name of a *function with receiver* cannot be the same as the name of some
1647public receiver method or field, otherwise a :index:`compile-time error` occurs.
1648It also means, that a *function with receiver* cannot overload a method,
1649defined for receiver type.
1650
1651*Function with receiver* can be generic as in the following example:
1652
1653.. code-block:: typescript
1654   :linenos:
1655
1656     function foo<T>(this: B<T>, p: T) {
1657          console.log (p)
1658     }
1659     function demo (p1: B<SomeClass>, p2: B<BaseClass>) {
1660         p1.foo(new SomeClass())
1661           // Type inference should determine the instantiating type
1662         p2.foo<BaseClass>(new DerivedClass())
1663          // Explicit instantiation
1664     }
1665
1666*Functions with receiver* are dispatched statically;
1667what function is being called is known at compile time based
1668on the receiver type specified in its declaration.
1669
1670They can be applied to receiver of any
1671derived class until it is redefined in the derived class:
1672
1673.. code-block:: typescript
1674   :linenos:
1675
1676      class Base { ... }
1677      class Derived extends Base { ... }
1678
1679      function foo(this: Base) { console.log ("Base.foo is called") }
1680      function foo(this: Derived) { console.log ("Derived.foo is called") }
1681
1682      let b: Base = new Base()
1683      b.foo() // `Base.foo is called` to be printed
1684      b = new Derived()
1685      b.foo() // `Base.foo is called` to be printed
1686      let d: Derived = new Derived()
1687      d.foo() // `Derived.foo is called` to be printed
1688
1689As illustrated by the following examples, a *function with receiver* can be
1690defined in a compilation unit other than one that defines a receiver type:
1691
1692.. code-block:: typescript
1693   :linenos:
1694
1695      // file a.sts
1696      class A {
1697          foo() { ... }
1698      }
1699
1700      // file ext.sts
1701      import {A} from "a.sts" // name 'A' is imported
1702      function bar(this: A) () {
1703         this.foo() // Method foo() is called
1704      }
1705
1706|
1707
1708.. _Receiver Type:
1709
1710Receiver Type
1711=============
1712
1713A *receiver type* is a type of *receiver parameter* in functions, function types
1714and lamdbas with receiver.
1715
1716A *receiver type* may be an interface type, a class type, an array type
1717or a type parameter, otherwise a :index:`compile-time error` occurs.
1718
1719Using an array type as receiever type is illustrated by the example below:
1720
1721.. code-block:: typescript
1722   :linenos:
1723
1724      function addElements(this: number[], ...s: number[]) {
1725       ...
1726      }
1727
1728      let x: number[] = [1, 2]
1729      x.addElements(3, 4)
1730
1731|
1732
1733.. _Accessors with Receiver:
1734
1735Accessors with Receiver
1736=======================
1737
1738.. meta:
1739    frontend_status: None
1740
1741An *accessor with receiver* declaration is a top-level declaration
1742(see :ref:`Top-Level Declarations`) that can be used as class or interface
1743accessors (see :ref:`Accessor Declarations`)
1744for specified receiver type:
1745
1746.. code-block:: abnf
1747
1748    accessorWithReceiverDeclaration:
1749          'get' identifier '(' receiverParameter ')' returnType block
1750        | 'set' identifier '(' receiverParameter ',' parameter ')' block
1751        ;
1752
1753A get-accessor (getter) must have a single *received parameter* and an explicit return type.
1754A set-accessor (setter) must have a *received parameter*, and a second parameter and no return type.
1755
1756The use of getters and setters looks the same as the use of fields:
1757
1758.. code-block:: typescript
1759   :linenos:
1760
1761      class Person {
1762        firstName: string
1763        lastName: string
1764        constructor (first: string, last: string) {...}
1765        ...
1766      }
1767
1768      get fullName(this: C): string {
1769        return this.LastName + ' ' + this.FirstName
1770      }
1771
1772      let c = new C("John", "Doe")
1773
1774      // as a method call:
1775      console.log(c.fullName) // output: 'Doe John'
1776      c.fullName = "new name" // compile-time error, as setter is not defined
1777
1778A :index:`compile-time error` occurs if an accessor is used in form of
1779a function or a method call.
1780
1781|
1782
1783.. _Function Types with Receiver:
1784
1785Function Types with Receiver
1786============================
1787
1788.. meta:
1789    frontend_status: None
1790
1791A *function type with receiver* specifies signature of functions or lambdas with receiver.
1792It is almost the same as a *function type* (see :ref:`Function Types`),
1793except that the first parameter is mandatory,
1794and keyword ``this`` is used as its name:
1795
1796.. code-block:: abnf
1797
1798    functionTypeWithReceiver:
1799        '(' receiverParameter (',' ftParameterList)? ')' ftReturnType 'throws'?
1800        ;
1801
1802The type of the *receiver parameter* is called a *receiver type*
1803(see :ref:`Receiver Type`).
1804
1805.. code-block:: typescript
1806   :linenos:
1807
1808      class A {...}
1809
1810      type FA = (this: A) => boolean
1811      type FN = (this: number[], max: number) => number
1812
1813*Function type with receiver* can be generic as in the following example:
1814
1815.. code-block:: typescript
1816   :linenos:
1817
1818      class B<T> {...}
1819
1820      type FB<T> = (this: B<T>, x: T): void
1821      type FBS = (this: B<string>, x: string): void
1822
1823
1824The usual rule of function type compatibility (see :ref:`Function Types Conversions`)
1825are applied to *function type with receiver*, ignoring parameters names.
1826
1827.. code-block:: typescript
1828   :linenos:
1829
1830      class A {...}
1831
1832      type F1 = (this: A) => boolean
1833      type F2 = (a: A) => boolean
1834
1835      function foo(this: A) => boolean {}
1836      function goo(a: A) => boolean {}
1837
1838      let f1: F1 = foo // ok
1839      f1 = goo // ok
1840
1841      let f2: F2 = goo // ok
1842      f2 = foo // ok
1843      f1 = f2 // ok
1844
1845The only difference is that only entity of function type with receiver can be
1846used in :ref:`Method Call Expression`. Using definitions from previous example:
1847
1848.. code-block:: typescript
1849   :linenos:
1850
1851      let a = new A()
1852      a.f1() // ok, function type with receiver
1853      f1(a)  // ok
1854
1855      a.f2() // compile-time error
1856      f2(a) // ok
1857
1858|
1859
1860.. _Lambda Expressions with Receiver:
1861
1862Lambda Expressions with Receiver
1863================================
1864
1865.. meta:
1866    frontend_status: None
1867
1868*Lambda expression with receiver* defines an instance of
1869a *function type with receiver* (see :ref:`Function Types with Receiver`).
1870
1871It looks almost the same as ordinary lambda expression
1872(see :ref:`Lambda Expressions`), except that the first parameter is mandatory,
1873and keyword ``this`` is used as its name:
1874
1875.. code-block:: abnf
1876
1877    lambdaExpressionWithReceiver:
1878        typeParameters? '(' receiverParameter (',' lambdaParameterList)? ')'
1879        returnType? throwMark? '=>' lambdaBody
1880        ;
1881
1882The keyword ``this`` can be used inside a *lamdba expression with receiver*
1883and it corresponds the first parameter:
1884
1885.. code-block:: typescript
1886   :linenos:
1887
1888      class A { name = "Bob" }
1889
1890      let show = (this: a): void {
1891          console.log(this.name)
1892      }
1893
1894The use of lambada  is illustrated by the example below:
1895
1896.. code-block:: typescript
1897   :linenos:
1898
1899      class A {
1900        name: string
1901        constructor (n: string) {
1902            this.name = n
1903        }
1904      }
1905
1906      function apply(aa: A[], f: (this: A) => void) {
1907        for (let a of aa) {
1908            a.f()
1909        }
1910      }
1911
1912      let aa: A[] = [new A("aa"), new A("bb")]
1913      foo(aa, (this: A) => { console.log(this.name)} ) // output: "aa" "bb"
1914
1915|
1916
1917.. _Trailing Lambdas:
1918
1919Trailing Lambdas
1920****************
1921
1922.. meta:
1923    frontend_status: Done
1924
1925The *trailing lambda* mechanism allows using a special form of function
1926or method call when the last parameter of a function or a method is of
1927function type, and the argument is passed as a lambda using the ``{}``
1928notation.
1929
1930Syntactically, the *trailing lambda* looks as follows:
1931
1932.. index::
1933   trailing lambda
1934   function call
1935   method call
1936   parameter
1937   function type
1938   method
1939   parameter
1940   lambda
1941   function type
1942
1943.. code-block:: typescript
1944   :linenos:
1945
1946      class A {
1947          foo (f: ()=>void) { ... }
1948      }
1949
1950      let a = new A()
1951      a.foo() { console.log ("method lambda argument is activated") }
1952      // method foo receives last argument as an inline lambda
1953
1954The formal syntax of the *trailing lambda* is presented below:
1955
1956.. code-block:: abnf
1957
1958    trailingLambdaCall:
1959        ( objectReference '.' identifier typeArguments?
1960        | expression ('?.' | typeArguments)?
1961        )
1962        arguments block
1963        ;
1964
1965
1966Currently, no parameter can be specified for the trailing lambda. Otherwise,
1967a :index:`compile-time error` occurs.
1968
1969**Note**: If a call is followed by a block, and the function or method
1970being called has no last function type parameter, then such block is
1971handled as an ordinary block of statements but not as a lambda function.
1972
1973In case of other ambiguities (e.g., when a function or method call has the
1974last parameter, which can be optional, of a function type), a syntax
1975production that starts with '{' following the function or method call is
1976handled as the *trailing lambda*.
1977If other semantics is needed, then the semicolon '``;``' separator can be used.
1978It means that the function or the method is to be called without the last
1979argument (see :ref:`Optional Parameters`).
1980
1981.. index::
1982   trailing lambda
1983   parameter
1984   block
1985   function
1986   method
1987   function type
1988   lambda function
1989   lambda
1990   semicolon
1991   call
1992
1993.. code-block:: typescript
1994   :linenos:
1995
1996      class A {
1997          foo (p?: ()=>void) { ... }
1998      }
1999
2000      let a = new A()
2001      a.foo() { console.log ("method lambda argument is activated") }
2002      // method foo receives last argument as an inline lambda
2003
2004      a.foo(); { console.log ("that is the block code") }
2005      // method 'foo' is called with 'p' parameter set to 'undefined'
2006      // ';' allows to specify explicitly that '{' starts the block
2007
2008      function bar(f: ()=>void) { ... }
2009
2010      bar() { console.log ("function lambda argument is activated") }
2011      // function 'bar' receives last argument as an inline lambda,
2012      bar(); { console.log ("that is the block code") }
2013      // function 'bar' is called with 'p' parameter set to 'undefined'
2014
2015
2016.. code-block:: typescript
2017   :linenos:
2018
2019     function foo (f: ()=>void) { ... }
2020     function bar (n: number) { ... }
2021
2022     foo() { console.log ("function lambda argument is activated") }
2023     // function foo receives last argument as an inline lambda,
2024
2025     bar(5) { console.log ("after call of 'bar' this block is executed") }
2026
2027     foo(() => { console.log ("function lambda argument is activated") })
2028     { console.log ("after call of 'foo' this block is executed") }
2029     /* here, function foo receives lambda as an argument and a block after
2030      the call is just a block, not a trailing lambda. */
2031
2032|
2033
2034.. _Enumeration Types Conversions:
2035
2036Enumeration Types Conversions
2037*****************************
2038
2039.. meta:
2040    frontend_status: Partly
2041
2042Every *enum* type is compatible with type ``Object`` (see
2043:ref:`Type Compatibility`). Every variable of type ``enum`` can thus be
2044assigned into a variable of type ``Object``. The ``instanceof`` check can
2045be used to get an enumeration variable back by applying the ``as`` conversion:
2046
2047.. code-block-meta:
2048
2049.. code-block:: typescript
2050   :linenos:
2051
2052    enum Commands { Open = "fopen", Close = "fclose" }
2053    let c: Commands = Commands.Open
2054    let o: Object = c // Autoboxing of enum type to its reference version
2055    // Such reference version type has no name, but can be detected by instanceof
2056    if (o instanceof Commands) {
2057       c = o as Commands // And explicitly converted back by 'as' conversion
2058    }
2059
2060.. index::
2061   enum type
2062   enumeration type
2063   conversion
2064   assignment
2065   Object
2066   variable
2067   compatibility
2068
2069|
2070
2071.. _Enumeration Methods:
2072
2073Enumeration Methods
2074*******************
2075
2076.. meta:
2077    frontend_status: Partly
2078
2079Several static methods are available to handle each enumeration type as follows:
2080
2081-  Method ``values()`` returns an array of enumeration constants in the order of
2082   declaration.
2083-  Method ``getValueOf(name: string)`` returns an enumeration constant with the
2084   given name, or throws an error if no constant with such name exists.
2085
2086.. index::
2087   enumeration method
2088   static method
2089   enumeration type
2090   enumeration constant
2091   error
2092   constant
2093
2094.. code-block:: typescript
2095   :linenos:
2096
2097      enum Color { Red, Green, Blue }
2098      let colors = Color.values()
2099      //colors[0] is the same as Color.Red
2100      let red = Color.valueOf("Red")
2101
2102There are additional methods for instances of any enumeration type:
2103
2104-  Method ``valueOf()`` returns an ``int`` or ``string`` value of an enumeration
2105   constant depending on the type of the enumeration constant.
2106
2107-  Method ``getName()`` returns the name of an enumeration constant.
2108
2109.. code-block-meta:
2110
2111.. code-block:: typescript
2112   :linenos:
2113
2114      enum Color { Red, Green = 10, Blue }
2115      let c: Color = Color.Green
2116      console.log(c.valueOf()) // prints 10
2117      console.log(c.getName()) // prints Green
2118
2119**Note**: ``c.toString()`` returns the same value as ``c.valueOf().toString()``.
2120
2121.. index::
2122   instance
2123   enumeration type
2124   value
2125   numeric type
2126   enumeration constant
2127   type int
2128   type string
2129
2130|
2131
2132.. _Exceptions:
2133
2134Exceptions
2135**********
2136
2137.. meta:
2138    frontend_status: Done
2139
2140``Exception`` is the base class of all exceptions. ``Exception`` is used to
2141define a new exception, or any class derived from the ``Exception`` as the
2142base of a class:
2143
2144.. code-block:: typescript
2145   :linenos:
2146
2147      class MyException extends Exception { ... }
2148
2149.. index::
2150   exception
2151   base class
2152   Exception
2153
2154A :index:`compile-time error` occurs if a generic class is a direct or
2155indirect subclass of ``Exception``.
2156
2157An exception is thrown explicitly with the ``throw`` statement.
2158
2159When an exception is thrown, the surrounding piece of code is to handle it by
2160correcting the problem, trying an alternative approach, or informing the user.
2161
2162An exception can  be  processed in two ways:
2163
2164-  Propagating the exception from a function to the code that calls that
2165   function (see :ref:`Throwing Functions`);
2166
2167-  Using a ``try`` statement to handle the exception (see :ref:`Try Statements`).
2168
2169.. index::
2170   exception
2171   base class
2172   Exception
2173   try statement
2174   throw statement
2175   propagation
2176   function
2177   throwing function
2178   function call
2179
2180|
2181
2182.. _Throwing Functions:
2183
2184Throwing Functions
2185==================
2186
2187.. meta:
2188    frontend_status: Done
2189
2190The keyword ``throws`` is used at the end of a signature to indicate that a
2191function (this notion here includes methods, constructors, or lambdas) can
2192throw an exception. A function ending with ``throws`` is called a
2193*throwing function*. The function type can also be marked as ``throws``:
2194
2195.. index::
2196   keyword throws
2197   throwing function
2198   signature
2199   method
2200   constructor
2201   lambda
2202   function
2203   exception
2204   function type
2205   throws mark
2206
2207.. code-block:: typescript
2208   :linenos:
2209
2210      function canThrow(x: int): int throws { ... }
2211
2212A *throwing function* can propagate exceptions to the scope from which
2213it is called. The propagation of an *exception* occurs if:
2214
2215-  The call of a *throwing function* is not enclosed in a ``try`` statement; or
2216-  The enclosed ``try`` statement does not contain a clause that can catch the
2217   exception.
2218
2219
2220In the example below, the function call is not enclosed in a ``try``
2221statement; any exception raised by ``canThrow`` function is propagated:
2222
2223.. index::
2224   throwing function
2225   propagation
2226   exception
2227   scope
2228   function call
2229   try statement
2230
2231.. code-block:: typescript
2232   :linenos:
2233
2234      function propagate1(x: int): int throws {
2235        return y = canThrow(x) // exception is propagated
2236      }
2237
2238
2239In the example below, the ``try`` statement can catch only ``this`` exceptions.
2240Any exception raised by ``canThrow`` function---except for ``MyException``
2241itself, and any exception derived from ``MyException``---is propagated:
2242
2243.. index::
2244   try statement
2245   this
2246   exception
2247   propagation
2248
2249.. code-block:: typescript
2250   :linenos:
2251
2252      function propagate2(x: int): int throws {
2253        try {
2254          return y = canThrow(x) //
2255        }
2256        catch (e: MyException) /*process*/ }
2257          return 0
2258      }
2259
2260|
2261
2262.. _Non-Throwing Functions:
2263
2264Non-Throwing Functions
2265======================
2266
2267.. meta:
2268    frontend_status: Done
2269
2270A *non-throwing function* is a function (this notion here includes methods,
2271constructors, or lambdas) not marked as ``throws``. Any exceptions inside a
2272*non-throwing function* must be handled inside the function.
2273
2274A :index:`compile-time error` occurs if not **all** of the following
2275requirements are met:
2276
2277-  The call of a *throwing function* is enclosed in a ``try`` statement;
2278-  The enclosing ``try`` statement has a default ``catch`` clause.
2279
2280.. index::
2281   non-throwing function
2282   throwing function
2283   function
2284   method
2285   constructor
2286   lambda
2287   throws mark
2288   try statement
2289   catch clause
2290
2291.. code-block-meta:
2292   expect-cte:
2293
2294.. code-block:: typescript
2295   :linenos:
2296
2297      // non-throwing function
2298      function cannotThrow(x: int): int {
2299        return y = canThrow(x) // compile-time error
2300      }
2301
2302      function cannotThrow(x: int): int {
2303        try {
2304          return y = canThrow(x) //
2305        }
2306        catch (e: MyException) { /* process */ }
2307        // compile-time error – default catch clause is required
2308      }
2309
2310|
2311
2312.. _Rethrowing Functions:
2313
2314Rethrowing Functions
2315====================
2316
2317.. meta:
2318    frontend_status: Done
2319
2320A *rethrowing function* is a function that accepts a *throwing function* as a
2321parameter, and is marked with the keyword ``rethrows``.
2322
2323The body of such function must not contain any ``throw`` statement that is
2324not handled by a ``try`` statement within that body. A function with unhandled
2325``throw`` statements must be marked with the keyword ``throws`` but not
2326``rethrows``.
2327
2328.. index::
2329   rethrowing function
2330   throwing function
2331   non-throwing function
2332   function parameter
2333   keyword throws
2334   keyword rethrows
2335   try statement
2336   throw statement
2337
2338Both a *throwing* and a *non-throwing* function can be an argument of a
2339*rethrowing function* ``foo`` that is being called.
2340
2341If a *throwing function* is an argument, then the calling of ``foo`` can
2342throw an exception.
2343
2344This rule is exception-free, i.e., a *non-throwing* function used as a call
2345argument cannot throw an exception:
2346
2347.. code-block:: typescript
2348   :linenos:
2349
2350        function foo (action: () throws) rethrows {
2351        action()
2352      }
2353
2354      function canThrow() {
2355        /* body */
2356      }
2357
2358      function cannotThrow() {
2359        /* body */
2360      }
2361
2362      // calling rethrowing function:
2363        foo(canThrow) // exception can be thrown
2364        foo(cannotThrow) // exception-free
2365
2366A call is exception-free if:
2367
2368-  Function ``foo`` has several parameters of a function type marked
2369   with ``throws``; and
2370-  All actual arguments of the call to ``foo`` are non-throwing.
2371
2372However, the call can raise an exception, and is handled as any other
2373*throwing function* call if at least one of the actual function arguments
2374is *throwing*. It implies that a call to ``foo`` within the body of a
2375*non-throwing* function must be guaranteed with a ``try-catch`` statement:
2376
2377.. index::
2378   function
2379   exception-free call
2380   function type parameter
2381   throws mark
2382   throwing function
2383   non-throwing function
2384   try-catch statement
2385
2386.. code-block:: typescript
2387   :linenos:
2388
2389      function mayThrowContext() throws {
2390        // calling rethrowing function:
2391        foo(canThrow) // exception can be thrown
2392        foo(cannotThrow) // exception-free
2393      }
2394
2395      function neverThrowsContext() {
2396        try {
2397          // calling rethrowing function:
2398          foo(canThrow) // exception can be thrown
2399          foo(cannotThrow) // exception-free
2400        }
2401        catch (e) {
2402          // To handle the situation
2403        }
2404      }
2405
2406|
2407
2408.. _Exceptions and Initialization Expression:
2409
2410Exceptions and Initialization Expression
2411========================================
2412
2413.. meta:
2414    frontend_status: Done
2415
2416A *variable declaration* (see :ref:`Variable Declarations`) or a *constant
2417declaration* (see :ref:`Constant Declarations`) expression used to initialize
2418a variable or constant must not have calls to functions that can *throw* or
2419*rethrow* exceptions if the declaration is not within a statement that handles
2420all exceptions.
2421
2422See :ref:`Throwing Functions` and :ref:`Rethrowing Functions` for details.
2423
2424.. index::
2425   variable declaration
2426   exception
2427   initialization expression
2428   constant declaration
2429   expression
2430   initialization
2431   variable
2432   constant
2433   function call
2434   throw exception
2435   rethrow exception
2436   statement
2437   throwing function
2438   rethrowing function
2439
2440|
2441
2442.. _Exceptions and Errors Inside Field Initializers:
2443
2444Exceptions and Errors Inside Field Initializers
2445===============================================
2446
2447.. meta:
2448    frontend_status: Done
2449
2450Class field initializers cannot call *throwing* or *rethrowing* functions.
2451
2452See :ref:`Throwing Functions` and :ref:`Rethrowing Functions` for details.
2453
2454.. index::
2455   exception
2456   error
2457   field initializer
2458   throwing function
2459   rethrowing function
2460
2461|
2462
2463.. _Coroutines:
2464
2465Coroutines
2466**********
2467
2468.. meta:
2469    frontend_status: Partly
2470    todo: rename valueOf(string) to getValueOf(string), implement valueOf()
2471
2472A function or lambda can be a *coroutine*. |LANG| supports *basic coroutines*,
2473*structured coroutines*, and *communication channels*.
2474Basic coroutines are used to create and launch a coroutine; the result is then
2475to be awaited.
2476
2477.. index::
2478   structured coroutine
2479   basic coroutine
2480   function
2481   lambda
2482   coroutine
2483   communication channel
2484   launch
2485
2486|
2487
2488.. _Create and Launch a Coroutine:
2489
2490Create and Launch a Coroutine
2491=============================
2492
2493.. meta:
2494    frontend_status: Done
2495
2496The following expression is used to create and launch a coroutine based on
2497a function call, a lambda call (see :ref:`Function Call Expression`), or a
2498method call (see :ref:`Method Call Expression`):
2499
2500.. code-block:: abnf
2501
2502      launchExpression:
2503        'launch' functionCallExpression | methodCallExpression;
2504
2505
2506.. code-block:: typescript
2507   :linenos:
2508
2509      let res = launch cof(10)
2510
2511      // where 'cof' can be defined as:
2512      function cof(a: int): int {
2513        let res: int
2514        // Do something
2515        return res
2516      }
2517
2518Lambda can be used in a launch expression as a part of a function call:
2519
2520.. code-block:: typescript
2521   :linenos:
2522
2523      let res = launch ((n: int) => { /* lambda body */ })(7)
2524
2525.. index::
2526   expression
2527   coroutine
2528   launch
2529   function call expression
2530   lambda
2531   launch expression
2532
2533The result of the launch expression is of type ``Promise<T>``, where ``T`` is
2534the return type of the function being called:
2535
2536.. code-block:: typescript
2537   :linenos:
2538
2539      function foo(): int {}
2540      function bar() {}
2541      let resfoo = launch foo()
2542      let resbar = launch bar()
2543
2544In the example above the type of ``resfoo`` is ``Promise<int>``, and the
2545type of ``resbar`` is ``Promise<void>``.
2546
2547Similarly to |TS|, |LANG| supports the launching of a coroutine by calling
2548the function ``async`` (see :ref:`Async Functions`). No restrictions apply as
2549to from what scope to call the function ``async``:
2550
2551.. index::
2552   launch expression
2553   return type
2554   function call
2555   coroutine
2556   async function
2557   restriction
2558
2559.. code-block:: typescript
2560   :linenos:
2561
2562      async function foo(): Promise<int> {}
2563
2564      // This will create and launch coroutine
2565      let resfoo = foo()
2566
2567|
2568
2569.. _Awaiting a Coroutine:
2570
2571Awaiting a Coroutine
2572====================
2573
2574.. meta:
2575    frontend_status: Done
2576
2577The ``await`` expressions are used while a previously launched coroutine
2578finishes and returns a value:
2579
2580.. code-block:: abnf
2581
2582      awaitExpression:
2583        'await' expression
2584        ;
2585
2586A :index:`compile-time error` occurs if the expression type is not ``Promise<T>``.
2587
2588.. index::
2589   expression await
2590   launch
2591   coroutine
2592   expression type
2593
2594.. code-block:: typescript
2595   :linenos:
2596
2597      let promise = launch (): int { return 1 } ()
2598      console.log(await promise) // output: 1
2599
2600If the coroutine result must be ignored, then the expression statement
2601``await`` is used:
2602
2603.. code-block:: typescript
2604   :linenos:
2605
2606      function foo() { /* do something */ }
2607      let promise = launch foo()
2608      await promise
2609
2610The ``await`` cannot return ``Promise<T>`` or union type that contains
2611``Promise<T>``. If the actual type argument of ``T`` in ``Promise<T>`` contains
2612``Promise``, then the compiler eliminates any such usage.
2613
2614Return types of ``await`` expressions are represented in the example below:
2615
2616.. code-block:: typescript
2617   :linenos:
2618
2619       // if p has type Promise<Promise<string>>,
2620       // await p returns string
2621       let x : string = await p;
2622
2623       // if p2 has type Promise<Promise<string> | number>,
2624       // await p2 returns string | number
2625       let y : string | number = await p2;
2626
2627       // if p3 has type Promise<string>|Promise<number>,
2628       // await p2 returns string | number
2629       let z : string | number = await p3;
2630
2631.. index::
2632   coroutine
2633   expression statement
2634   union type
2635   type argument
2636   await expression
2637
2638|
2639
2640.. _Promise<T> Class:
2641
2642``Promise<T>`` Class
2643====================
2644
2645.. meta:
2646    frontend_status: Done
2647
2648The class ``Promise<T>`` represents the values returned by launch expressions
2649(see :ref:`Create and Launch a Coroutine`) and dynamic import expressions (see
2650:ref:`Dynamic Import Expression`). It belongs to the core packages of the
2651standard library (see :ref:`Standard Library`), and can be used without
2652any qualification.
2653
2654The methods are used as follows:
2655
2656-  ``then`` takes two arguments (the first argument is the callback used if the
2657   promise is fulfilled, and the second if it is rejected), and returns
2658   ``Promise<U>``.
2659
2660.. index::
2661   class
2662   value
2663   launch expression
2664   import expression
2665   argument
2666   callback
2667   package
2668   standard library
2669   method
2670
2671.. code-block:: typescript
2672
2673        Promise<U> Promise<T>::then<U>(fulfilCallback :
2674            function
2675        <T>(val: T) : Promise<U>, rejectCallback : (err: Object)
2676        : Promise<U>)
2677
2678-  ``catch`` is the alias for ``Promise<T>.then<U>((value: T) : U => {}``, ``onRejected)``.
2679
2680.. code-block-meta:
2681
2682.. code-block:: typescript
2683
2684        Promise<U> Promise<T>::catch<U>(rejectCallback : (err:
2685            Object) : Promise<U>)
2686
2687-  ``finally`` takes one argument (the callback called after ``promise`` is
2688   either fulfilled or rejected) and returns ``Promise<T>``.
2689
2690.. index::
2691   alias
2692   callback
2693   call
2694
2695.. code-block:: typescript
2696
2697        Promise<U> Promise<T>::finally<U>(finallyCallback : (
2698            Object:
2699        T) : Promise<U>)
2700
2701|
2702
2703.. _Structured Coroutines:
2704
2705Structured Coroutines
2706=====================
2707
2708.. meta:
2709    frontend_status: None
2710
2711|
2712
2713.. _Channels Classes:
2714
2715Channels Classes
2716================
2717
2718.. meta:
2719    frontend_status: None
2720
2721*Channels* are used to send data between coroutines.
2722
2723*Channels classes* are a part of the coroutine-related package of the
2724standard library (see :ref:`Standard Library`).
2725
2726.. index::
2727   channel class
2728   coroutine
2729   package
2730
2731|
2732
2733Async Functions and Methods
2734***************************
2735
2736.. meta:
2737    frontend_status: Done
2738
2739|
2740
2741.. _Async Functions:
2742
2743``Async`` Functions
2744===================
2745
2746.. meta:
2747    frontend_status: Done
2748
2749``Async`` functions are implicit coroutines that can be called as regular
2750functions. ``Async`` functions can be neither ``abstract`` nor ``native``.
2751
2752The return type of an ``async`` function must be ``Promise<T>`` (see
2753:ref:`Promise<T> Class`). Returning values of types ``Promise<T>`` and ``T``
2754from ``async`` functions is allowed.
2755
2756Using return statement without an expression is allowed if the return type
2757is ``Promise<void>``.
2758*No-argument* return statement can be added implicitly as the last statement
2759of the function body if there is no explicit return statement in a function
2760with the return ``Promise<void>``.
2761
2762**Note**: Using type ``Promise<void>`` is not recommended as this type is
2763supported for the sake of backward |TS| compatibility only.
2764
2765.. index::
2766   function async
2767   coroutine
2768   return type
2769   function body
2770   backward compatibility
2771   annotation
2772   no-argument return statement
2773   async function
2774   return statement
2775   compatibility
2776
2777|
2778
2779.. _Experimental Async Methods:
2780
2781Experimental ``Async`` Methods
2782==============================
2783
2784.. meta:
2785    frontend_status: Done
2786
2787The method ``async`` is an implicit coroutine that can be called as a regular
2788method. ``Async`` methods can be neither ``abstract`` nor ``native``.
2789
2790The return type of an ``async`` method must be ``Promise<T>`` (see
2791:ref:`Promise<T> Class`). Returning values of types ``Promise<T>`` and *T* from
2792``async`` methods is allowed.
2793
2794Using return statement without an expression is allowed if the return type
2795is ``Promise<void>``.
2796*No-argument* return statement can be added implicitly as the last statement
2797of the methods body if there is no explicit return statement in a method
2798with return type ``Promise<void>``.
2799
2800**Note**: Using this annotation is not recommended as this type of methods
2801is supported for the sake of backward |TS| compatibility only.
2802
2803.. index::
2804   async method
2805   coroutine
2806   return type
2807   function body
2808   compatibility
2809   no-argument return statement
2810   annotation
2811   abstract method
2812   native method
2813
2814|
2815
2816.. _DynamicObject Type:
2817
2818DynamicObject Type
2819******************
2820
2821.. meta:
2822    frontend_status: Partly
2823
2824The interface ``DynamicObject`` is used to provide seamless interoperability
2825with dynamic languages (e.g., |JS| and |TS|), and to support advanced
2826language features such as *dynamic import* (see :ref:`Dynamic Import Expression`).
2827
2828This interface (defined in :ref:`Standard Library`) is common for a set of
2829wrappers (also defined in :ref:`Standard Library`) that provide access to
2830underlying objects.
2831
2832An instance of ``DynamicObject`` cannot be created directly. Only an
2833instance of a specific wrapper object can be instantiated. For example, a
2834*dynamic import* expression (see :ref:`Dynamic Import Expression`) can produce
2835an instance of the dynamic object implementation class that wraps an object
2836containing exported entities of an imported module.
2837
2838``DynamicObject`` is a predefined type. The following operations applied to an
2839object of type ``DynamicObject`` are handled by the compiler in a special manner:
2840
2841- Field access;
2842- Method call;
2843- Indexing access;
2844- New; and
2845- Cast.
2846
2847.. index::
2848   interface
2849   interoperability
2850   dynamic import
2851   interface
2852   wrapper
2853   access
2854   underlying object
2855   instantiation
2856   export
2857   entity
2858   import
2859   predefined type
2860   field access
2861   indexing access
2862   method call
2863   cast
2864
2865|
2866
2867.. _DynamicObject Field Access:
2868
2869``DynamicObject`` Field Access
2870==============================
2871
2872.. meta:
2873    frontend_status: Partly
2874    todo: now it supports only JSValue, need to add full abstract support
2875
2876The field access expression *D.F*, where *D* is of type ``DynamicObject``,
2877is handled as an access to a property of an underlying object.
2878
2879If the value of a field access is used, then it is wrapped in the instance of
2880``DynamicObject``, since the actual type of the field is not known at compile
2881time.
2882
2883.. code-block:: typescript
2884   :linenos:
2885
2886   function foo(d: DynamicObject) {
2887      console.log(d.f1) // access of the property named "f1" of underlying object
2888      d.f1 = 5 // set a value of the property named "f1"
2889      let y = d.f1 // 'y' is of type DynamicObject
2890   }
2891
2892The wrapper can raise an error if:
2893
2894- No property with the specified name exists in the underlying object; or
2895- The field access is in the right-hand side of the assignment, and the
2896  type of the assigned value is not compatible with the type of the property
2897  (see :ref:`Type Compatibility`).
2898
2899.. index::
2900   wrapper
2901   dynamic import
2902   underlying object
2903   field access
2904   field access expression
2905   compile time
2906   property
2907   instance
2908   assignment
2909   assigned value
2910
2911
2912|
2913
2914.. _DynamicObject Method Call:
2915
2916``DynamicObject`` Method Call
2917=============================
2918
2919.. meta:
2920    frontend_status: Partly
2921    todo: now it supports only JSValue, need to add full abstract support
2922
2923The method call expression *D.F(arguments)*, where *D* is of type
2924``DynamicObject``, is handled as a call of the instance method of an
2925underlying object.
2926
2927If the result of a method call is used, then it is wrapped in the instance
2928of ``DynamicObject``, since the actual type of the returned value is not known
2929at compile time.
2930
2931.. code-block:: typescript
2932   :linenos:
2933
2934   function foo(d: DynamicObject) {
2935      d.foo() // call of a method "foo" of underlying object
2936      let y = d.goo() // 'y' is of type DynamicObject
2937   }
2938
2939The wrapper must raise an error if:
2940
2941- No method with the specified name exists in the underlying object; or
2942- The signature of the method is not compatible with the types of the
2943  call arguments.
2944
2945.. index::
2946   DynamicObject
2947   wrapper
2948   method
2949   dynamic import
2950   field access
2951   property
2952   instance
2953   method
2954
2955|
2956
2957.. _DynamicObject Indexing Access:
2958
2959``DynamicObject`` Indexing Access
2960=================================
2961
2962.. meta:
2963    frontend_status: Partly
2964    todo: now it supports only JSValue, need to add full abstract support
2965
2966The indexing access expression *D[index]*, where *D* is of type
2967``DynamicObject``, is handled as an indexing access to an underlying object.
2968
2969
2970.. code-block-meta:
2971
2972.. code-block:: typescript
2973   :linenos:
2974
2975   function foo(d: DynamicObject) {
2976      let x = d[0]
2977   }
2978
2979The wrapper must raise an error if:
2980
2981- The indexing access is not supported by the underlying object;
2982- The type of the *index* expression is not supported by the underlying object.
2983
2984.. index::
2985   indexing access expression
2986   index expression
2987   wrapper
2988   access
2989   underlying object
2990
2991|
2992
2993.. _DynamicObject New Expression:
2994
2995``DynamicObject`` New Expression
2996================================
2997
2998.. meta:
2999    frontend_status: Partly
3000    todo: now it supports only JSValue, need to add full abstract support
3001
3002The new expression *new D(arguments)* (see :ref:`New Expressions`), where
3003*D* is of type ``DynamicObject``, is handled as a new expression (constructor
3004call) applied to the underlying object.
3005
3006The result of the expression is wrapped in an instance of ``DynamicObject``,
3007as the actual type of the returned value is not known at compile time.
3008
3009.. code-block:: typescript
3010   :linenos:
3011
3012   function foo(d: DynamicObject) {
3013      let x = new d()
3014   }
3015
3016The wrapper must raise an error if:
3017
3018- A new expression is not supported by the underlying object; or
3019- The signature of the constructor of the underlying object is not compatible
3020  with the types of call arguments.
3021
3022.. index::
3023   expression
3024   constructor call
3025   constructor
3026   wrapper
3027   returned value
3028   compatibility
3029   call argument
3030   property
3031   instance
3032
3033|
3034
3035.. _DynamicObject Cast Expression:
3036
3037``DynamicObject`` Cast Expression
3038=================================
3039
3040.. meta:
3041    frontend_status: None
3042
3043The cast expression *D as T* (see :ref:`Cast Expressions`), where *D* is of
3044type ``DynamicObject``, is handled as an attempt to cast the underlying object
3045to a static type ``T``.
3046
3047A :index:`compile-time error` occurs if ``T`` is not a class or interface type.
3048
3049The result of a cast expression is an instance of type ``T``.
3050
3051.. code-block:: typescript
3052   :linenos:
3053
3054   interface I {
3055      bar()
3056   }
3057
3058   function foo(d: DynamicObject) {
3059      let x = d as I
3060      x.bar() // a call of interface method (not dynamic)
3061   }
3062
3063The wrapper must raise an error if an underlying object cannot be converted
3064to the target type specified by the cast operator.
3065
3066.. index::
3067   wrapper
3068   underlying object
3069   cast expression
3070   interface type
3071   cast expression
3072   instance
3073   type
3074   conversion
3075   target type
3076   cast operator
3077
3078|
3079
3080.. _Packages:
3081
3082Packages
3083********
3084
3085.. meta:
3086    frontend_status: Partly
3087    todo: Implement compiling a package module as a single compilation unit - #16267
3088
3089One or more *package modules* form a package:
3090
3091.. code-block:: abnf
3092
3093      packageDeclaration:
3094          packageModule+
3095          ;
3096
3097*Packages* are stored in a file system or a database (see
3098:ref:`Compilation Units in Host System`).
3099
3100A *package* can consist of several package modules if all such modules
3101have the same *package header*:
3102
3103.. index::
3104   package module
3105   package
3106   file system
3107   database
3108   package header
3109   module
3110
3111.. code-block:: abnf
3112
3113      packageModule:
3114          packageHeader packageModuleDeclaration
3115          ;
3116
3117      packageHeader:
3118          'package' qualifiedName
3119          ;
3120
3121      packageModuleDeclaration:
3122          importDirective* packageTopDeclaration*
3123          ;
3124
3125      packageTopDeclaration:
3126          topDeclaration | packageInitializer
3127          ;
3128
3129A :index:`compile-time error` occurs if:
3130
3131-  A *package module* contains no package header; or
3132-  Package headers of two package modules in the same package have
3133   different identifiers.
3134
3135Every *package module* can directly use all exported entities from the core
3136packages of the standard library (see :ref:`Standard Library Usage`).
3137
3138A *package module* can directly access all top-level entities declared in all
3139modules that constitute the package.
3140
3141.. index::
3142   package module
3143   package header
3144   package
3145   identifier
3146   core package
3147   import
3148   exported entity
3149   access
3150   top-level entity
3151   module
3152   standard library
3153   simple name
3154
3155|
3156
3157.. _Internal Access Modifier Experimental:
3158
3159Internal Access Modifier
3160========================
3161
3162.. meta:
3163    frontend_status: Partly
3164    todo: Implement in libpandafile, implement semantic, now it is parsed and ignored - #16088
3165
3166The modifier ``internal`` indicates that a class member, a constructor, or
3167an interface member is accessible (see :ref:`Accessible`) within its
3168compilation unit only. If the compilation unit is a package (see
3169:ref:`Packages`), then ``internal`` members can be used in any
3170*package module*. If the compilation unit is a separate module (see
3171:ref:`Separate Modules`), then ``internal`` members can be used within this
3172module.
3173
3174.. index::
3175   modifier
3176   access modifier
3177   accessibility
3178   interface
3179   class member
3180   constructor
3181   access
3182   package module
3183   module
3184
3185.. code-block:: typescript
3186   :linenos:
3187
3188      class C {
3189        internal count: int
3190        getCount(): int {
3191          return this.count // ok
3192        }
3193      }
3194
3195      function increment(c: C) {
3196        c.count++ // ok
3197      }
3198
3199.. index::
3200   member
3201   constructor
3202   internal modifier
3203   access
3204
3205|
3206
3207.. _Package Initializer:
3208
3209Package Initializer
3210===================
3211
3212.. meta:
3213    frontend_status: None
3214
3215Among all *package modules* there can be one to contain a code that performs
3216initialization actions (e.g., setting initial values for variables across all
3217package modules) as described in detail in :ref:`Compilation Unit Initialization`.
3218The appropriate syntax is presented below:
3219
3220.. index::
3221   package initializer
3222   package module
3223   initialization
3224   compilation unit
3225   variable
3226   package initializer
3227
3228.. code-block:: abnf
3229
3230      packageInitializer:
3231          'static' block
3232          ;
3233
3234A :index:`compile-time error` occurs if a package contains more than one
3235*package initializer*.
3236
3237|
3238
3239.. _Import and Overloading of Function Names:
3240
3241Import and Overloading of Function Names
3242========================================
3243
3244.. meta:
3245    frontend_status: Done
3246
3247While importing functions, the following situations can occur:
3248
3249-  Different imported functions have the same name but different signatures, or
3250   a function (functions) of the current module and an imported function
3251   (functions) have the same name but different signatures. This situation is
3252   *overloading*. All such functions are accessible (see :ref:`Accessible`).
3253
3254-  A function (functions) of the current module and an imported function
3255   (functions) have the same name and overload-equivalent signature (see
3256   :ref:`Overload-Equivalent Signatures`). This situation is a
3257   :index:`compile-time error` as declarations are duplicated. Qualified import
3258   or alias in import can be used to access the imported entity.
3259
3260.. index::
3261   import
3262   function
3263   overloading
3264   function name
3265   function
3266   imported function
3267   signature
3268   module
3269   access
3270   accessibility
3271
3272The two situations are illustrated by the examples below:
3273
3274.. code-block-meta:
3275   skip
3276
3277.. code-block:: typescript
3278   :linenos:
3279
3280      // Overloading case
3281      package P1
3282      function foo(p: int) {}
3283
3284      package P2
3285      function foo(p: string) {}
3286
3287      // Main module
3288      import {foo} from "path_to_file_with_P1"
3289      import {foo} from "path_to_file_with_P2"
3290
3291      function foo (p: double) {}
3292
3293      function main() {
3294        foo(5) // Call to P1.foo(int)
3295        foo("A string") // Call to P2.foo(string)
3296        foo(3.141592653589) // Call to local foo(double)
3297      }
3298
3299
3300      // Declaration duplication case
3301      package P1
3302         function foo() {}
3303      package P2
3304         function foo() {}
3305      // Main program
3306      import {foo} from "path_to_file_with_P1"
3307      import {foo} from "path_to_file_with_P2" /* Error: duplicating
3308          declarations imported*/
3309      function foo() {} /* Error: duplicating declaration identified
3310          */
3311      function main() {
3312        foo() // Error: ambiguous function call
3313        // But not a call to local foo()
3314        // foo() from P1 and foo() from P2 are not accessible
3315      }
3316
3317|
3318
3319.. _Generics Experimental:
3320
3321Generics Experimental
3322*********************
3323
3324|
3325
3326.. _NonNullish Type Parameter:
3327
3328NonNullish Type Parameter
3329=========================
3330
3331.. meta:
3332    frontend_status: None
3333
3334If some generic class has a type parameter with nullish union type constraint,
3335then special syntax for type annotation can be used to get a non-nullish
3336version of the type parameter variable. The example below illustrates this
3337possibility:
3338
3339.. index::
3340   generic class
3341   type parameter
3342   nullish union type
3343   constraint
3344   annotation
3345   non-nullish type
3346   variable
3347   parameter
3348
3349.. code-block:: typescript
3350   :linenos:
3351
3352      class A<T> {  // in fact it extends Object|null|undefined
3353          foo (p: T): T! { // foo returns non-nullish value of p
3354             return p!
3355          }
3356      }
3357
3358      class B<T extends SomeType | null> {
3359          foo (p: T): T! { // foo returns non-nullish value of p
3360             return p!
3361          }
3362      }
3363
3364      class C<T extends SomeType | undefined> {
3365          foo (p: T): T! { // foo returns non-nullish value of p
3366             return p!
3367          }
3368      }
3369
3370      let a = new A<Object>
3371      let b = new B<SomeType>
3372      let c = new C<SomeType>
3373
3374      let result: Object = new Object  // Type of result is non-nullish !
3375      result = a.foo(result)
3376      result = b.foo(new SomeType)
3377      result = c.foo(new SomeType)
3378
3379      // All such assignments are type-valid as well
3380      result = a.foo(void)      // void! => never
3381      result = b.foo(null)      // null! => never
3382      result = c.foo(undefined) // undefined! => never
3383
3384
3385.. raw:: pdf
3386
3387   PageBreak
3388