erg/doc/EN/syntax/29_decorator.md
Shunsuke Shibayama 6dc8c5015b Fix links
2022-08-14 17:31:46 +09:00

2.7 KiB

Decorator

Decorators are used to add or make explicit a specific state or behavior for a type or function. The syntax for decorators is as follows.

@deco
X = ...

There can be more than one decorator, as long as they do not conflict.

A decorator is not a special object; its entity is simply a single-argument function. A decorator is equivalent to the following pseudo code.

X = ...
X = deco(X)

Since Erg does not allow reassignment, the above code will not pass, and a decorator is required. Here are some frequently used built-in decorators.

Inheritable

Indicates that the type being defined is an inheritable class. If the scope argument is set to "public", the class can be inherited by classes in external modules. By default, it is "private" and cannot be inherited from outside.

Final

disables overriding the "final" method. If you attach it to a class, it becomes a non-inheritable class, but since it is the default, it is meaningless.

Override

Use to override an attribute, which by default Erg will fail if you try to define an attribute that is the same as the base class.

Impl

Indicates implementation of the argument trace.

Add = Trait {
    . `_+_` = Self.(Self) -> Self
}
Sub = Trait {
    . `_-_` = Self.(Self) -> Self
}

C = Class({i = Int}, Impl: Add and Sub)
C.
    @Impl Add.
    `_+_` self, other = C.new {i = self::i + other::i}
    @Impl Sub
    `_-_` self, other = C.new {i = self::i - other::}

Attach

Specifies the attachment patch that comes with the trait by default. This allows you to reproduce the same behavior as the Rust trait.

# foo.er
Add R, O = Trait {
    . `_+_` = Self.(R) -> O
}
@Attach IntIsBinAdd, OddIsBinAdd
BinAdd = Subsume Add(Self, Self.AddO), {
    .AddO = Type
}

IntIsBinAdd = Patch(Int, Impl: BinAdd)
AddO = Int
OddIsBinAdd = Patch(Odd, Impl: BinAdd)
OddIsBinAdd.AddO = Even

This way, when you import traits from other modules, the attachment patch is automatically applied.

# Originally IntIsBinAdd, OddIsBinAdd must be imported at the same time, but can be omitted with attachment patch
{BinAdd; ...} = import "foo"

assert Int.AddO == Int
assert Odd.AddO == Even

Internally, they are only connected together using the trait's .attach method. If there is a conflict, it can be removed using the trace's .detach method.

@Attach X
T = Trait ...
assert X in T.attaches
U = T.detach(X).attach(Y)
assert X not in U.attaches
assert Y in U.attaches

Deprecated

Indicates that the variable is outdated and deprecated.

Test

Indicates a subroutine for tests. Test subroutines are executed with the erg test command.

Previous | Next