|
1 | 1 | module TermInterface |
2 | 2 |
|
3 | | -""" |
4 | | - iscall(x) |
5 | | -Returns `true` if `x` is a function call expression. If true, `operation`, `arguments` |
6 | | -must also be defined for `x`. |
7 | | -""" |
8 | | -iscall(x) = false |
9 | | -export iscall |
10 | | - |
11 | 3 | """ |
12 | 4 | isexpr(x) |
13 | | -Returns `true` if `x` is an expression tree (an S-expression). If true, `head` and `children` methods must be defined for `x`. |
| 5 | +Returns `true` if `x` is an expression tree. If true, `head(x)` and `children(x)` methods must be defined for `x`. |
| 6 | +Optionally, if `x` represents a function call, `iscall(x)` should be true, and `operation(x)` and `arguments(x)` should also be defined. |
14 | 7 | """ |
15 | 8 | isexpr(x) = false |
16 | 9 | export isexpr |
17 | 10 |
|
18 | | - |
19 | 11 | """ |
20 | | - issym(x) |
| 12 | + iscall(x) |
| 13 | +Returns `true` if `x` is a function call expression. If true, `operation(x)`, `arguments(x)` |
| 14 | +must also be defined for `x`. |
21 | 15 |
|
22 | | -Returns `true` if `x` is a symbol. If true, `nameof` must be defined |
23 | | -on `x` and must return a Symbol. |
| 16 | +If `iscall(x)` is true, then also `isexpr(x)` *must* be true. The other way around is not true. |
| 17 | +(A function call is always an expression node, but not every expression tree represents a function call). |
| 18 | +
|
| 19 | +This means that, `head(x)` and `children(x)` must be defined. Together |
| 20 | +with `operation(x)` and `arguments(x)`. |
| 21 | +
|
| 22 | +## Examples |
| 23 | +
|
| 24 | +In a functional language, all expression trees are function calls (e.g. SymbolicUtils.jl). |
| 25 | +Let's say that you have an hybrid array and functional language. `iscall` on the expression `v[i]` |
| 26 | +is `false`, and `iscall` on expression `f(x)` is `true`, but both of them are nested |
| 27 | +expressions, and `isexpr` is `true` on both. |
| 28 | +
|
| 29 | +The same goes for Julia `Expr`. An `Expr(:block, ...)` is *not a function call* |
| 30 | +and has no `operation` and `arguments`, but has a `head` and `children`. |
| 31 | +
|
| 32 | +
|
| 33 | +The distinction between `head`/`children` and `operation`/`arguments` is needed |
| 34 | +when dealing with languages that are *not representing function call operations as their head*. |
| 35 | +The main example is `Expr(:call, :f, :x)`: it has both a `head` and an `operation`, which are |
| 36 | +respectively `:call` and `:f`. |
| 37 | +
|
| 38 | +In other symbolic expression languages, such as SymbolicUtils.jl, the `head` of a node |
| 39 | +can correspond to `operation` and `children` can correspond to `arguments`. |
24 | 40 | """ |
25 | | -issym(x) = false |
26 | | -export issym |
| 41 | +iscall(x) = false |
| 42 | +export iscall |
27 | 43 |
|
28 | 44 | """ |
29 | 45 | head(x) |
|
0 commit comments