mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
Fix definition of recursive functions with fn.
Also document explicitly that the function body may refer to the function being defined. This fixes #1206.
This commit is contained in:
parent
7932f58201
commit
d140e98f3c
|
@ -171,9 +171,10 @@ func compileFn(cp *compiler, fn *parse.Form) effectOp {
|
|||
bodyNode := args.nextMustLambda()
|
||||
args.mustEnd()
|
||||
|
||||
index := cp.thisScope().add(name + FnSuffix)
|
||||
op := cp.lambda(bodyNode)
|
||||
|
||||
return fnOp{cp.thisScope().add(name + FnSuffix), op}
|
||||
return fnOp{index, op}
|
||||
}
|
||||
|
||||
type fnOp struct {
|
||||
|
|
|
@ -108,6 +108,10 @@ func TestBuiltinSpecial(t *testing.T) {
|
|||
// fn.
|
||||
That("fn f [x]{ put x=$x'.' }; f lorem; f ipsum").
|
||||
Puts("x=lorem.", "x=ipsum."),
|
||||
// Recursive functions with fn. Regression test for #1206.
|
||||
That("fn f [n]{ if (== $n 0) { put 1 } else { * $n (f (- $n 1)) } }; f 3").
|
||||
Puts(6.0),
|
||||
|
||||
// return.
|
||||
That("fn f []{ put a; return; put b }; f").Puts("a"),
|
||||
)
|
||||
|
|
|
@ -1587,7 +1587,7 @@ written to a file or a pipe will be discarded. Examples:
|
|||
- Assuming the file `data` contains a single line `hello`,
|
||||
`only-values < data` will not do anything.
|
||||
|
||||
# Special Commands
|
||||
# Special commands
|
||||
|
||||
**Special commands** obey the same syntax rules as normal commands, but have
|
||||
evaluation rules that are custom to each command. Consider the following
|
||||
|
@ -1868,6 +1868,15 @@ c
|
|||
**TODO**: Find a better way to describe this. Hopefully the example is
|
||||
illustrative enough, though.
|
||||
|
||||
The lambda may refer to the function being defined. This makes it easy to define
|
||||
recursive functions:
|
||||
|
||||
```elvish-transcript
|
||||
~> fn f [n]{ if (== $n 0) { put 1 } else { * $n (f (- $n 1)) } }
|
||||
~> f 3
|
||||
▶ (float64 6)
|
||||
```
|
||||
|
||||
Under the hood, `fn` defines a variable with the given name plus `~` (see
|
||||
[variable suffix](#variable-suffix)).
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user