mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-17 14:47:21 +03:00
[sc-684] Disable forwarding of free vars in ask terms
This commit is contained in:
parent
0ce59d9721
commit
3a6c746fd6
@ -1,7 +1,7 @@
|
|||||||
use super::{parser::TermParser, Book, Name, Num, Pattern, Term};
|
use super::{parser::TermParser, Book, Name, Num, Pattern, Term};
|
||||||
use crate::maybe_grow;
|
use crate::maybe_grow;
|
||||||
|
|
||||||
const BUILTINS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/fun/builtins.hvm"));
|
const BUILTINS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/fun/builtins.bend"));
|
||||||
|
|
||||||
pub const LIST: &str = "List";
|
pub const LIST: &str = "List";
|
||||||
pub const LCONS: &str = "List/cons";
|
pub const LCONS: &str = "List/cons";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
diagnostics::Diagnostics,
|
diagnostics::Diagnostics,
|
||||||
fun::{Ctx, Name, Pattern, Term},
|
fun::{Ctx, Name, Term},
|
||||||
maybe_grow,
|
maybe_grow,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@ -41,15 +41,9 @@ impl Term {
|
|||||||
let fun = make_fun_name(typ);
|
let fun = make_fun_name(typ);
|
||||||
|
|
||||||
if def_names.contains(&fun) {
|
if def_names.contains(&fun) {
|
||||||
let mut fvs = nxt.free_vars();
|
// TODO: come up with a strategy for forwarding free vars to prevent infinite recursion.
|
||||||
pat.binds().flatten().for_each(|bind| _ = fvs.remove(bind));
|
let nxt = Term::lam(*pat.clone(), std::mem::take(nxt));
|
||||||
let fvs = fvs.into_keys().collect::<Vec<_>>();
|
*self = Term::call(Term::Ref { nam: fun.clone() }, [*val.clone(), nxt]);
|
||||||
let nxt = fvs
|
|
||||||
.iter()
|
|
||||||
.fold(*nxt.clone(), |nxt, nam| Term::lam(Pattern::Var(Some(nam.clone())), nxt.clone()));
|
|
||||||
let nxt = Term::lam(*pat.clone(), nxt);
|
|
||||||
let term = Term::call(Term::Ref { nam: fun.clone() }, [*val.clone(), nxt]);
|
|
||||||
*self = Term::call(term, fvs.into_iter().map(|nam| Term::Var { nam }));
|
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("Could not find definition {} for type {}.", fun, typ));
|
return Err(format!("Could not find definition {} for type {}.", fun, typ));
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
source: tests/golden_tests.rs
|
source: tests/golden_tests.rs
|
||||||
input_file: examples/bitonic_sort.bend
|
input_file: examples/bitonic_sort.bend
|
||||||
---
|
---
|
||||||
523776
|
16515072
|
||||||
|
@ -2,4 +2,30 @@
|
|||||||
source: tests/golden_tests.rs
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/recursive_bind.bend
|
input_file: tests/golden_tests/run_file/recursive_bind.bend
|
||||||
---
|
---
|
||||||
λa (a 0)
|
[4m[1m[31mErrors:[0m
|
||||||
|
[1mThe following functions contain recursive cycles incompatible with HVM's strict evaluation:[0m
|
||||||
|
* Foo -> Foo
|
||||||
|
|
||||||
|
The greedy eager evaluation of HVM may cause infinite loops.
|
||||||
|
[1mRefactor these functions to use lazy references instead of direct function calls.[0m
|
||||||
|
A reference is strict when it's being called ('(Foo x)') or when it's used non-linearly ('let x = Foo; (x x)').
|
||||||
|
It is lazy when it's an argument ('(x Foo)') or when it's used linearly ('let x = Foo; (x 0)').
|
||||||
|
|
||||||
|
[1mTry one of these strategies:[0m
|
||||||
|
- Use pattern matching with 'match', 'fold', and 'bend' to automatically lift expressions to lazy references.
|
||||||
|
- Replace direct calls with combinators. For example, change:
|
||||||
|
'Foo = λa λb (b (λc (Foo a c)) a)'
|
||||||
|
to:
|
||||||
|
'Foo = λa λb (b (λc λa (Foo a c)) (λa a) a)'
|
||||||
|
which is lifted to:
|
||||||
|
'Foo = λa λb (b Foo__C1 Foo_C2 a)'
|
||||||
|
- Replace non-linear 'let' expressions with 'use' expressions. For example, change:
|
||||||
|
'Foo = λf let x = Foo; (f x x)'
|
||||||
|
to:
|
||||||
|
'Foo = λf use x = Foo; (f x x)'
|
||||||
|
which inlines to:
|
||||||
|
'Foo = λf (f Foo Foo)'
|
||||||
|
- If disabled, re-enable the default 'float-combinators' and 'linearize-matches' compiler options.
|
||||||
|
|
||||||
|
For more information, visit: https://github.com/HigherOrderCO/hvm-lang/blob/main/docs/lazy-definitions.md.
|
||||||
|
To disable this check, use the "-Arecursion-cycle" compiler option.
|
||||||
|
Loading…
Reference in New Issue
Block a user