mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +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 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 LCONS: &str = "List/cons";
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
diagnostics::Diagnostics,
|
||||
fun::{Ctx, Name, Pattern, Term},
|
||||
fun::{Ctx, Name, Term},
|
||||
maybe_grow,
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
@ -41,15 +41,9 @@ impl Term {
|
||||
let fun = make_fun_name(typ);
|
||||
|
||||
if def_names.contains(&fun) {
|
||||
let mut fvs = nxt.free_vars();
|
||||
pat.binds().flatten().for_each(|bind| _ = fvs.remove(bind));
|
||||
let fvs = fvs.into_keys().collect::<Vec<_>>();
|
||||
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 }));
|
||||
// TODO: come up with a strategy for forwarding free vars to prevent infinite recursion.
|
||||
let nxt = Term::lam(*pat.clone(), std::mem::take(nxt));
|
||||
*self = Term::call(Term::Ref { nam: fun.clone() }, [*val.clone(), nxt]);
|
||||
} else {
|
||||
return Err(format!("Could not find definition {} for type {}.", fun, typ));
|
||||
}
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: examples/bitonic_sort.bend
|
||||
---
|
||||
523776
|
||||
16515072
|
||||
|
@ -2,4 +2,30 @@
|
||||
source: tests/golden_tests.rs
|
||||
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