Skip to content
Anton Zherdev edited this page May 22, 2014 · 11 revisions

class ::=
[<annotations>]
<class_modifiers> <class | object | trait | enum | struct | package object>
[className]¹ [<generics>] [(<constructor_field>, [<constructor_field>, ...])]²
[extends superClass[(<call_parameters>)]³ [with superTrait1 [with superTrait2 ...]] ]⁴ [{
    <enum_constant>⁵
    ...
    <class_statement>
    ...
}]
class_modifiers ::= [private | public]⁶ [stub] [case⁷ | abstract | final]//in any order
enum_constant ::= name(<call_parameters>)
class_statement ::= <class_field> | <definition>
call_parameters ::= [<call_parameter>[, <call_parameter> ...]]
call_parameter ::= [parameterName = ] <\expression>

  1. The name should be omitted for a package object.
  2. The class constructor. Traits cannot contain constructors. Constructor can be only one. As alternative constructors you can use an apply function.
  3. Class can extend only one class and must set the constructor parameters of the superclass if it is necessary.
  4. Class can extend many traits. Traits have no constructor.
  5. The list of constants for enum class.
  6. Default visibility is public. Private classes are visible only inside the file.
  7. Case classes are immutable classes. The equals and hash functions will be auto generated according to constructor fields.

Constructor field

constructor_field ::= <constructor_field_modifiers> [val | var]¹ name [: <datatype>]² [= <expression>]³
constructor_field_modifiers ::= [<visibility>]⁴ [override] [weak]⁵_//in any order_

  1. You can use val or var modifiers to declare a class field. Otherwise the value of the constructor field would be available only for definition other class fields.

  2. Data type of the parameter could be omitted when you use the default value.

  3. Default expression for the constructor field.

  4. Default visibility is public.

  5. Use weak reference to avoid retain cycle in Objective-C.

    class Foo(val bar : int, val p = 0)

Class field

class_field ::= <field_modifiers> <val | var>¹ name [: <datatype>]² [= <expression>]³
field_modifiers ::= [<visibility>]⁴ [lazy]⁵ [volatile]⁶ [override] //in any order
visibility ::= private | protected | public

¹ - val - immutable, var - mutable
² - data type of the field could be inferred using the expression, so it's possible to omit it
³ - expression for initial value of the field. It could be omitted only for an optional data type
⁴ - default visibility is public
⁵ - lazy fields are calculated at the time of a first call
⁶ - put the memory barrier after changing of the field to guarantee the order of operations

val foo : int = 0
lazy val bar = foo*foo

Definition

definition ::= [<annotations>] <def_modifiers> def name[<generics>][([<self_parameter>, ]<parameter>[, <parameter>...])] <[: <datatype>]¹ [= <expression>]² | {<expressions>}³>
def_modifiers ::= [<visibility>]⁴ [final]⁵ [override]⁶ [static]⁷ [inline]⁸ //in any order

¹ - data type of the definition could be inferred using the expression, so it's possible to omit it
² - expression could be omitted for abstract functions
³ - to create a procedure you have to use braces without equal sign
⁴ - default visibility is public
⁵ - prohibit overriding of the function
⁶ - it's necessary to put this modifier when you override or implement the function
⁷ - static modifier would be removed soon. It's better to use objects.
⁸ - inline the code of the function in places of call. It's useful to reduce number of function calls and to avoid creation of lambdas.

def square(x : int) = x*x
def square(x : int) : int = x*x
def procedure(x : int) {
    log("x = $x")
}

Parameter

parameter ::= [weak]¹ name [: <datatype>]² [= <expression>]³

¹ - this works only with lambdas. It's necessary to avoid memory leaks in Objective-C. When you save a block in a field, it's possible that the block will retain an object. This situation can lead to retain cycle. This modifier replaces direct call of class fields or functions with call using a weak reference.
² - data type of the parameter could be omitted when you use the default value.
³ - default value of the parameter. If you don't point a value of the parameter in a call, the default value will be used.

def foo(f : int -> int, bar = 1)

Self parameter

self_parameter ::= self : <datatype>

if the class contains generics you can define a function for the particular type of the generic using this construction. You can also define generics of the function using generic of the class.

class Foo<X>(val bar : [X]) {
    def flat<Y>(self : Foo<[Y]>) : [Y] = {
        val arr = ArrayBuilder<Y>()
        bar.for{ys ->
            ys.cast<[Y]>.for{y ->
                arr.append(y)
            }
        }
        arr.build
    }
}

val foo = Foo<[int]>([[1, 0], [3]])
assertEquals([1, 0, 3], foo.flat)

Generics

generics ::= < <generic> [, <generic> ...] >
generic ::= name [ extends super1 [with super2 [with super3 ...]]

Clone this wiki locally