Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Local blocks with parameters is the gross way to do it. The right way to do it is Phi/Upsilon form.

https://gist.github.com/pizlonator/cf1e72b8600b1437dda8153ea...

But even if you used block arguments, it's so very different from a lambda. Lambdas allow dynamic creation of variables, while SSA doesn't. Therefore, in SSA, variables must-alias themselves, while in the lambda calculus they don't. If you think that a block that takes arguments is the same as a lambda because you're willing to ignore such huge differences, then what's the limiting principle that would make you say that two languages really are different from one another?

Remember, all Turing complete languages are "conceptually the same" in the sense that you can compile them to one another



Phi/Upsilon is even more obviously equivalent to blocks with parameters than phi nodes were. It's storing to a "shadow variable" that you "load from" in the phi, i.e. it's exactly the same "store to ABI specified location in caller, load from it in callee" as a function call.


> Phi/Upsilon is even more obviously equivalent to blocks with parameters than phi nodes were

Then you don't understand Phi/Upsilon


It does seem to rhyme with how function calls work under the hood.

When people say equivalent, it is usually not in the mathematical sense, which would be meaningless here because all forms are turing complete anyway.

Take equivalent as--similarity that helps you understand A given you know B, and perhaps some of the wisdom from B translates to A.


> It does seem to rhyme with how function calls work under the hood.

You're just overindexing on the fact that block "arguments" are called "arguments". In SSA with block arguments, you can pass data to a block without passing it as an argument. The arguments are just a way of expressing Phis.

And in Phi/Upsilon, this is valid:

    MyBlock:
        X = Whatever(...)
        Upsilon(X, ^Y)
        Y = Phi()
Note how I'm using an upsilon to set the shadow variable of a Phi that's in the same block. You can't do that with block arguments.

These things just aren't the same at all. Saying that they are the same just shows that you don't get it.

> When people say equivalent, it is usually not in the mathematical sense, which would be meaningless here because all forms are turing complete anyway.

But they're not equivalent even in a mathematical sense.

> Take equivalent as--similarity that helps you understand A given you know B, and perhaps some of the wisdom from B translates to A.

If you want to understand these things, then focus on how they are so very different rather than brain damaging yourself into thinking they are similar


> You're just overindexing on the fact that block "arguments" are called "arguments"

But that's what it is. Briefly stated, your "upsilon" is just picking the 'actual' argument for the 'formal' parameter in a matching "phi". That's exactly what a function call does, and this holds even though you've intentionally decoupled the "upsilon" and "phi" nodes from any control-flow "jump" construct.

> Note how I'm using an upsilon to set the shadow variable of a Phi that's in the same block. You can't do that with block arguments.

Classically, the phi node would sit at the top of a block anyway, and this arrangement helps significantly in computing dominator set properties, renaming and use-def chains etc. etc. Giving up that property makes everything more awkward, including proofs of correctness for transformations, minimality, etc.


> But that's what it is. Briefly stated, your "upsilon" is just picking the 'actual' argument for the 'formal' parameter in a matching "phi". That's exactly what a function call does, and this holds even though you've intentionally decoupled the "upsilon" and "phi" nodes from any control-flow "jump" construct.

By that argument, every store instruction is an "argument". And basic block arguments and lambda calculus are equivalent to people storing and loading to memory willy nilly.

As I said before, these equivalence claims are so nonsensical because if you take the arguments to their limits, you end up with all languages being equivalent to one another

> Classically, the phi node would sit at the top of a block anyway, and this arrangement helps significantly in computing dominator set properties, renaming and use-def chains etc. etc. Giving up that property makes everything more awkward, including proofs of correctness for transformations, minimality, etc.

All of those things that Phi-at-top-of-blocks works with also work in the Phi/Upsilon world


In CS-411 we teach both SSA and parameterized blocks, with more emphasis on SSA. IMHO the main advantage is that phis are connected to their "call" sites and argument values. Blocks aren't first class, there's no need to decouple the names of their inputs from the actual inputs. SSA makes those dataflow connections explicit, which is obviously superior.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: