move posts in directory by year
This commit is contained in:
63
app/views/posts/2016/_03-07-mixup-of-levels.haml
Normal file
63
app/views/posts/2016/_03-07-mixup-of-levels.haml
Normal file
@@ -0,0 +1,63 @@
|
||||
%p
|
||||
Writing Soml helped a lot to separate the levels, or phases of the ruby compilation process. Helped
|
||||
me that is, to plan the ruby compiler.
|
||||
%p
|
||||
But off course i had not written the ruby compiler, i have only
|
||||
%a{:href => "https://dancinglightning.gitbooks.io/the-object-machine/content/object/dynamic_types.html"} planned
|
||||
how the dynamic nature could be implemented, using soml. In very short summary, the plan was to
|
||||
extend somls feature with esoteric multi-return features and use that to jump around different
|
||||
implementation when types change.
|
||||
%h2#the-benefit-of-communication The benefit of communication
|
||||
%p
|
||||
But first a thanks. When i was in the US, i talked to quite a few people about my plans. Everything
|
||||
helped, but special thanks goes to Caleb for pointing out two issues.
|
||||
%p
|
||||
The simpler one is that what i had named Layout, is usually called Type. I have changed the code
|
||||
and docs now and must admit it is a better name.
|
||||
%p
|
||||
The other thing Caleb was right about is that Soml is what is called an intermediate representation.
|
||||
This rubbed a little, especially since i had just moved away from a purely intermediate
|
||||
representation to an intermediate language. But still, we’ll see below that the language is not
|
||||
enough to solve the dynamic issues. I have already created an equivalent intermediate
|
||||
representation (to the soml ast) and will probably let go of the language completely, in time.
|
||||
%p
|
||||
So thanks to Caleb, and a thumbs up for anyone else reading, to
|
||||
%strong make contact
|
||||
%h2#the-hierarchy-of-languages The hierarchy of languages
|
||||
%p
|
||||
It seemed like such a good idea. Just like third level languages are compiled down to second (ie c
|
||||
to assembler), and second is compiled to first (ie assembler to binary), so fourth level would
|
||||
get compiled down to third. Such a nice clean world, very appealing.
|
||||
%p
|
||||
Until i started working on the details. Specifically how the type (of almost anything) would change
|
||||
in a statically typed language. And in short, I ran into yet another wall.
|
||||
%p
|
||||
So back it is to using an intermediate representation. Alas, at least it is a working one, so down
|
||||
from there to executable, it is know to work.
|
||||
%h2#cross-function-jumps Cross function jumps
|
||||
%p
|
||||
Let’s call a method something akin to what ruby has. It’s bound to a type, has a name and arguments.
|
||||
But both return types and argument types are not specified. Then function could be a specific
|
||||
implementation of that method, specific to a certain set of types for the arguments. The return type
|
||||
%br/
|
||||
is still not fixed.
|
||||
%p
|
||||
A compiler can generate all possible functions for a method as the set of basic types is small. Or
|
||||
it could be a little cleverer and generate stubs and generate the actual functions on demand, as
|
||||
probably only a fraction of the theoretical possibilities will be needed.
|
||||
%p
|
||||
Now, if we have an assignment, say to an argument, from a method call, the type of the variable
|
||||
may have to change according to the return type.
|
||||
So the return will be to different addresses (think of it as an if) and so in each branch,
|
||||
code can be inserted to change the type. But that makes the rest of the function behave wrongly as
|
||||
it assumes the type before the change.
|
||||
%p
|
||||
And this is where the cross function jumps come. Which is also the reason this can not be expressed
|
||||
in a language. The code then needs to jump to the same place, in a different function.
|
||||
%p
|
||||
The function can be pre-compiled or compiled on demand at that point. All that matters is that the
|
||||
logic of the function being jumped to is the same as where the jump comes from. And this is
|
||||
guaranteed by the fact that both function are generated from the same (untyped ruby) source code.
|
||||
%h2#next-steps Next steps
|
||||
%p So what’s left to do here: There is the little matter of implementing this plan.
|
||||
%p Maybe it leads to another wall, maybe this is it. Fingers crossed.
|
||||
108
app/views/posts/2016/_07-26-the-road-ahead.haml
Normal file
108
app/views/posts/2016/_07-26-the-road-ahead.haml
Normal file
@@ -0,0 +1,108 @@
|
||||
%p So, the plan, in short:
|
||||
%ol
|
||||
%li I need to work a little more on docs. Reading them i notice they are still not up to date
|
||||
%li The Type system needs work
|
||||
%li The Method-Function relationship needs to be created
|
||||
%li Ruby compiler needs to be written
|
||||
%li Parfait moves back completely into ruby land
|
||||
%li Soml parser should be scrapped (or will become redundant by 2-4)
|
||||
%li The memory model needs reworking (global not object based memory)
|
||||
%h3#type-system 2. Type system
|
||||
%p
|
||||
A Type is an ordered list of associations from name to BasicType (Object/Integer). The class exists
|
||||
off course and has been implemented as an array with the names and BasicTypes laid out in sequence.
|
||||
This is basically fine, but support for navigation is missing.
|
||||
%p
|
||||
The whole type system is basically graph. A type
|
||||
%em A
|
||||
is connected to a type
|
||||
%em B
|
||||
if it has exactly
|
||||
one different BasicType. So
|
||||
%em A
|
||||
needs to have
|
||||
%strong exactly
|
||||
the same names, and
|
||||
%strong exactly
|
||||
one
|
||||
different BasicType. Another way of saying this is that the two types are related if in the class
|
||||
that Type represents, exactly one variable changes type. This is off course exactly what happens
|
||||
when an assignment assigns a different type.
|
||||
%p
|
||||
%em A
|
||||
and
|
||||
%em B
|
||||
are also related when
|
||||
%em A
|
||||
has exactly one more name entry than
|
||||
%em B
|
||||
, but os otherwise
|
||||
identical. This is what happens when a new variable is added too a class, or one is removed.
|
||||
%p
|
||||
The implementation needs to establish this graph (possibly lazily), so that the traversal is fast.
|
||||
The most likely implementation seems a hash, so a hashing function has to be designed and the equals
|
||||
implemented.
|
||||
%h3#method-function-relationship 3. Method-Function relationship
|
||||
%p
|
||||
Just to get the naming clear: A method is at the ruby level, untyped. A Class has references to
|
||||
Methods.
|
||||
%p
|
||||
Whereas a Function is at the level below, fully typed.
|
||||
Function’s arguments and local variables have a BasicType.
|
||||
Type has references to Functions.
|
||||
%p
|
||||
A Function’s type is fully described by the combination of the arguments Type and the Frame Type.
|
||||
The Frame object is basically a wrapper for all local variables.
|
||||
%p
|
||||
A (ruby) Method has N Function “implementations”. One function for each different combination of
|
||||
BasicTypes for arguments and local variables. Functions know which Method they belong to, because
|
||||
their parent Type class holds a reference to the Class that the Type describes.
|
||||
%h3#ruby-compiler 4. Ruby Compiler
|
||||
%p
|
||||
Currently there is only the Function level and the soml compiler. The ruby level / compiler is
|
||||
missing.
|
||||
%p
|
||||
The Compiler generates Class objects, and Type objects as far as it can determine name and
|
||||
BasicTypes of the instance variables.
|
||||
%p
|
||||
Then it creates Method objects for every Method parsed. Finally it must create all functions that
|
||||
needed. In a first brute-force approach this may mean creating functions for all possible
|
||||
type combinations.
|
||||
%p
|
||||
Call-sites must then be “linked”. Linking here refers to the fact that the compiler can not
|
||||
determine how to call a function before it is created. So the functions get created in a first pass
|
||||
and calls and returns “linked” in a second. The return addresses used at the “soml” level are
|
||||
dependent on the BasicType that is being returned. This involves associating the code labels (at
|
||||
the function level) with the ast nodes they come from (at the method level). With this, the compiler
|
||||
ensures that the type of the variable receiving the return value is correct.
|
||||
%h3#parfait-in-ruby 5. Parfait in ruby
|
||||
%p
|
||||
After SOML was originally written, parts of the run-time (parfait) was ported to soml. This was done with the
|
||||
idea that the run-time is low level and thus needs to be fully typed. As it turns out this is only
|
||||
partly correct, in the sense that there needs to exist Function definitions (in the sense above)
|
||||
that implement basic functionality. But as the sub-chapter on the ruby compiler should explain,
|
||||
this does not mean the code has to written in a typed language.
|
||||
%p
|
||||
After the ruby-compiler is implemented, the run-time can be implemented in ruby. While this may seem
|
||||
strange at first, one must remember that the ruby-compiler creates N Functions of each method for
|
||||
all possible type combinations. This means if the ruby method is correctly implemented, error
|
||||
handling, for type errors, will be correctly generated by the compiler.
|
||||
%h3#soml-goodbye 6. SOML goodbye
|
||||
%p
|
||||
By this time the soml language can be removed. Meaning the parser for the language and all
|
||||
documentation is not needed. The ruby-complier compilers straight into the soml internal
|
||||
representation (as the soml parser) and because parfait is back in ruby land, soml should be
|
||||
removed. Which is a relief, because there are definitely enough languages in the world.
|
||||
%h3#memory-model-rework 7. Memory model rework
|
||||
%p
|
||||
Slightly unrelated to the above (read: can be done at the same time), the memory model needs to be
|
||||
expanded. The current per object
|
||||
%em fake
|
||||
memory works fine, but leaves memory management in
|
||||
the compiler.
|
||||
%p
|
||||
Since ultimately memory management should be part of the run-time, the model needs to be changed
|
||||
to a global one. This means class Page and Space should be implemented, and the
|
||||
%em fake
|
||||
memory
|
||||
mapped to a global array.
|
||||
Reference in New Issue
Block a user