|
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