ruby-x.github.io/app/views/posts/_2017-2-3-of-slopes-and-chains-and-changes-in-the-air.haml

89 lines
5.0 KiB
Plaintext
Raw Normal View History

2018-04-10 18:50:07 +02:00
%p
As i said in the last post, a step back and forward, possibly two, was taken and understanding
grows again. Especially when i think that some way is the way, it always changes and i turn out
to be at least partially wrong. The way of life, of imperfect intelligence, to strive for that
perfection that is forever out of reach. Heres the next installment.
%h2#slopes-and-ramps Slopes and Ramps
%p
When thinking about method caching and how to implement it i came across this thing that i will
call a Slope for now. The Slope of a function that is. At least thats where the thought started.
%p The Slope of a function is a piece of code that has two main properties:
%ul
%li
it is straight, up to the end. i mean it has no branches from the outside.
It may have internally but that does not affect anything.
%li it ends in a branch that returns (a call), but this is not part of the Slope
%p
Those
%em two
properties would better be called a Ramp. The Ramp the function goes along before it
jumps of to the next function.
%p
The
%strong Slope
is the part before the jump. So a Ramp is a Slope and a Jump.
%p
Code in the Slope, it struck me, has the unique possibility of doing a jump, with out worrying about
returning. After all, it knows there is a call coming. After contemplating this a little i
found the flaw, which one understands when thinking about where the function returns to. So Slope
can jump away without caring if (and only if) the return address is set to after that jump (and the
address is actually set by the code before the jump).
%p
Remembering that we set the return address in the caller (not as in c the callee) we can arrange
for that. And so we can write Slope code that just keeps going. Because once the return address
is set up, the code can just keep jumping forward. The only thing is that the call must come.
%p
In more concrete terms: Method caching can be a series of checks and jumps. If the check is ok
we call, otherwise jump on. And even the last fail (the switches default case) can be a jump
to what we would otherwise call a method. A method that determines the real jump target from
the type (of self, in the message) and calls it. Except its not a method because it never
returns, which is symmetrically to us not calling it.
%p
So this kind of “method” which is not really a method, but still a fair bit of logic, ill call
a Slope.
%h2#links-and-chains Links and Chains
%p
A Slope, the story continues, is really just a specific case of something else. If we take away
the expectation that a call is coming, we are left with a sequence of code with jumps to more
code. This could be called a Chain, and each part of the Chain would be a Link.
%p
To define that: a
%strong Link
is sequence of code that ends in a jump. It has no other jumps, just
the one at the end. And the jump at the end jumps to another Link.
%p The Code i am talking about here is risc level code, one could say assembler instructions.
%p
The concept though is very familiar: at a higher level the Link would be a Statement and a
Chain a sequence of Statements. Were missing the branch abstraction yet, but otherwise this is
a lower level description of code in a similar way as the typed level Code and Statements are
a description of higher level code.
%h2#typed-level-is-wrong Typed level is wrong
%p
The level that is nowadays called Typed, and used to be soml, is basically made up of language
constructs. It does not allow for manipulation of the risc level. As the ruby level is translated
to the typed level, which in turn is translated to the risc level, the ruby compiler has no
way of manipulating the risc level. This is as it should be.
%p
The problem is just, that the constructs that are currently at the typed level, do not allow
to express the results needed at the risc level.
%p
Through the history of the development the levels have become mixed up. It is relatively clear at
the ruby level what kind of construct is needed at the risc level. This is what has to drive the
constructs at the typed level. We need access to these kinds of Slope or Link ideas at the ruby
level.
%p
Another way of looking at the typed level inadequacies is the size of the codes generated. Some of
the expressions (or statements) resolve to 2 or 3 risc instructions. Others, like the call, are
15. This is an indication that part of the level is wrong. A good way to architect the layers
would result in an
%em even
expansion of the amount of code at every level.
%h2#too-little-testing Too little testing
%p
The ruby compiler should really drive the development more. The syntax and behavior of ruby are
quite clear, and i feel the risc layer is quite a solid target. So before removing too much or
rewriting too much i shall just add more (and more) functionality to the typed layer.
%p
At the same time some of the concepts (like a method call) will probably not find any use, but
as long as they dont harm, i shall leave them lying around.