No holes in closures
In Wombat closures are the only block structure. So closures are often called immediately that they are created, and it is easy to forget that they are potentially independent entities. In particular it is clearly wrong to allow references to external identifiers to refer to ones which are still holes and don't have values at the time of closure creation. For one thing the closure will run differently before and after the hole is filled.Holes should only be passed to closures at closure execution time, via the input parameter ($) and the output (`$). So the code for the appendTest example (from Logic Programming in Functional Style) should be:
`append = { # $ is 2 input listscase $ of [ # nb. "case x of y" just maps to "caseP y x" { $ = ([],`y); y } { $ = (`hdx +> `tlx, `y); hdx +> append(tlx,y) } ] }; print( append([1 2],[3 4])); # [1 2 3 4] [1 2 3 4] = append([1 2],print(`a)); # [3 4] [1 2 3 4] = append(print(`b),[3 4]); # [1 2]
And the code for the factorial example (from Quantum, Entropic and Entangled computation) should be:
`fact = { case $:Nat of [
{ $ = 0; 1}
{ $ = `n >? 0; n*fact(n-1)}
]
};
6 = fact `x; print x
Case Behaviour
Another problem in the factorial example is that the 2nd option won't terminate without substantial and inappropriate compiler cleverness, as the rules stand. I could use firstCase instead, which would work in this particular example, but it is a hack (even though it is the only case construct in most languages). So my current thinking is that when running backwards and matching the output instead of the input it should act like anyCase and abort other branches when a match is found. But I don't think that is quite the right answer.
No comments:
Post a Comment