mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 05:11:09 +00:00
156 lines
3.8 KiB
Markdown
156 lines
3.8 KiB
Markdown
# Special form
|
|
|
|
Special forms are operators, subroutines (and the like) that cannot be expressed in the Erg type system. It is surrounded by ``, but it cannot actually be captured.
|
|
Also, types such as `Pattern`, `Body`, and `Conv` appear for convenience, but such types do not exist. Its meaning also depends on the context.
|
|
|
|
## `=`(pat: Pattern, body: Body) -> NoneType
|
|
|
|
Assign body to pat as a variable. Raise an error if the variable already exists in the same scope or if it doesn't match pat.
|
|
It is also used in record attribute definitions and default arguments.
|
|
|
|
```python
|
|
record = {i = 1; j = 2}
|
|
f(x: Int, y = 2) = ...
|
|
```
|
|
|
|
`=` has special behavior when the body is a type or a function.
|
|
The variable name on the left side is embedded in the object on the right side.
|
|
|
|
```python
|
|
print! Class() # <class <lambda>>
|
|
print! x: Int -> x + 1 # <function <lambda>>
|
|
C = Class()
|
|
print! c # <class C>
|
|
f = x: Int -> x + 1
|
|
print! f # <function f>
|
|
gx: Int = x + 1
|
|
print! g # <function g>
|
|
KX: Int = Class(...)
|
|
print! K # <kind K>
|
|
L = X: Int -> Class(...)
|
|
print! L # <kind L>
|
|
```
|
|
|
|
The `=` operator has a return value of "undefined".
|
|
Multiple assignments and `=` in functions result in syntax errors.
|
|
|
|
```python
|
|
i = j = 1 # SyntaxError: multiple assignments are not allowed
|
|
print!(x=1) # SyntaxError: cannot use `=` in function arguments
|
|
# hint: did you mean keyword arguments (`x: 1`)?
|
|
if True, do:
|
|
i = 0 # SyntaxError: A block cannot be terminated by an assignment expression
|
|
```
|
|
|
|
## `->`(pat: Pattern, body: Body) -> Func
|
|
|
|
Generate anonymous functions, function types.
|
|
|
|
## `=>`(pat: Pattern, body: Body) -> Proc
|
|
|
|
Generate anonymous procedure, procedure type.
|
|
|
|
## `.`(obj, attr)
|
|
|
|
Read attributes of obj.
|
|
`x.[y, z]` will return the y and z attributes of x as an array.
|
|
|
|
## `|>`(obj, c: Callable)
|
|
|
|
Execute `c(obj)`. `x + y |>.foo()` is the same as `(x + y).foo()`.
|
|
|
|
### |T: Type|(x: Option T)`?` -> T
|
|
|
|
Postfix operator. Call `x.unwrap()` and `return` immediately in case of error.
|
|
|
|
## `:`(x, T)
|
|
|
|
Declares that object `x` is of type `T`. An error is raised if `x` is not a subtype of `T`.
|
|
|
|
It can be used for variable declarations or as the right-hand side value of an expression.
|
|
|
|
```erg
|
|
# both are OK
|
|
x: Int = 1
|
|
y = x: Int
|
|
```
|
|
|
|
## `as`(x, T)
|
|
|
|
Forces the object `x` to be cast to type `T`. If `x` is not a subtype of `T`, an error is raised.
|
|
The difference from `:` is that `(x: T): U` when `x: U; U <: T`, but `(x as T): T`.
|
|
|
|
## match(obj, *lambdas: Lambda)
|
|
|
|
For obj, execute lambdas that match the pattern.
|
|
|
|
```python
|
|
match[1, 2, 3]:
|
|
(l: Int) -> log "this is type of Int"
|
|
[[a], b] -> log a, b
|
|
[*a] -> log a
|
|
# (one two three)
|
|
```
|
|
|
|
## Del|T: Type|(*x: T) -> NoneType
|
|
|
|
Delete the variable `x`. However, built-in objects cannot be deleted.
|
|
|
|
```python
|
|
a = 1
|
|
Del a # OK
|
|
|
|
Del True # SyntaxError: cannot delete a built-in object
|
|
```
|
|
|
|
## do(body: Body) -> Func
|
|
|
|
Generate an anonymous function with no arguments. Syntactic sugar for `() ->`.
|
|
|
|
## do!(body: Body) -> Proc
|
|
|
|
Generate an anonymous procedure with no arguments. Syntactic sugar for `() =>`.
|
|
|
|
## set operator
|
|
|
|
### `[]`(*objs)
|
|
|
|
Creates an array from arguments or a dict from optional arguments.
|
|
|
|
### `{}`(*objs)
|
|
|
|
Create a set from arguments.
|
|
|
|
### `{}`(*fields: ((Field, Value); N))
|
|
|
|
Generate a record.
|
|
|
|
### `{}`(layout, *names, *preds)
|
|
|
|
Generates a refinement type.
|
|
|
|
### `*`
|
|
|
|
Expand a nested collection. It can also be used for pattern matching.
|
|
|
|
```python
|
|
[x, *y] = [1, 2, 3]
|
|
assert x == 1 and y == [2, 3]
|
|
assert [x, *y] == [1, 2, 3]
|
|
assert [*y, x] == [2, 3, 1]
|
|
{x; *yz} = {x = 1; y = 2; z = 3}
|
|
assert x == 1 and yz == {y = 2; z = 3}
|
|
assert {x; *yz} == {x = 1; y = 2; z = 3}
|
|
```
|
|
|
|
## virtual operator
|
|
|
|
Operators that cannot be used directly by the user.
|
|
|
|
### ref|T: Type|(x: T) -> Ref T
|
|
|
|
Returns an immutable reference to the object.
|
|
|
|
### ref!|T!: MutType|(x: T!) -> Ref! T!
|
|
|
|
Returns a mutable reference to a mutable object.
|