Comment by barfbagginus
8 months ago
Re: name. Fold and bend are indeed called fold and unfold in Haskell and traditional functional programming literature.
I wonder if bend has to do with how we manipulate the computation's interaction graph while evaluating a bend. There might be some bending of wires!
Re: code example
In the code example, x=0 is the seed value. tree = fork(0) must mean "fork off to evaluate the bend at the seed value". In that first fork, we fork twice with the value x=1, to get the left and right subtrees of the top level node. We then fork four instances of x=2, eight instances of x = 3, and finally get our balanced binary tree with eight 7s.
Note this is guesswork. I don't know what the ![a, b] syntax means, and I haven't read much of the guide.
Appendix: Notes on Fold Vs Bend
I wrote these for an earlier draft while reminding myself about these operations. I include them more for my benefit, and in case they help you or the audience.
Fold and bend are categorical duals, aka catamorphisms and anamorphisms. One takes a monadic value and reduces it into an ordinary value. The other takes an ordinary value and expands it into a comonadic value.
Fold starts with a value in an inductive data type, and then replaces its constructors with a function. For example it takes a list (1:2):3, and replaces the constructor : with the function `+`, to get (1+2)+3 = 6
Bend starts with a seed value and a function taking values into constructor expressions for a conductive data type. It then grows the seed into a potentially infinite AST. For example the seed value 1 and the function f(x:xs) = (x+1) : (x:xs) gives us the infinite lazy list [1, 2, 3, ...]
The question that comes to me is: can I use fork(x) outside of a bend?
Seems like probably not, there doesn't seem to be enough information in the 'argument' to this 'function' to do anything useful without the implicit context of the bend construct.
For that reason I think I'd prefer it if fork was a keyword (like 'bend' and 'when') rather than a 'function', just at the surface syntax level to give a clue it is something special.
I guess fork is a kind of 'magic' function that represents the body of the bend. It's a bit like a 'self' or 'this'.
At the moment this syntax is in a weird half-way point ...the underlying concept is necessarily functional but it's trying to look kind of like an imperative for-loop still.
I wonder if we couldn't just explicitly create a 'bendable' recursive function that can be 'bent' by calling it. But I guess it's like this because it needs to be tightly constrained by the 'when' and 'else' forms.
TBH the more I look at this example the more confusing it is. The other part I wonder about is the assigning of new values to tree var... can I set other local vars from outside the bend scope? I don't think so, I guess it'd be a syntax error if the var names assigned in the 'when' and 'else' clauses didn't match?
Again it's sort of overloading an imperative-looking syntax to implicitly do the 'return' from the implicit recursive function.
Later on there is this example:
And here I wonder - does 'width' have a value after the bend? Or it's only the last assignment in each clause that is privileged?
That's an odd mix in a language which otherwise has explicit returns like Python.
If so I wonder if a syntax something like this might be clearer:
i.e. name the return var once in the bend itself, yield intermediate values (to itself, recursively) and return the final state.