It was one of most powerful software.
But the behavior is rather different from typical programs which takes a limited pattern of data structure as input and return also limited pattern of data.
for instance typical method/function takes some data like int, and returns another object or data like if you put a coin to a vendor machine and push selection button, you get candy etc. quite mechanical.
On the other hand compiler can take million of line code code and generate something which can perform very complex thing as output, this is more like something only human can do.
the interesting nature is in compiler, in the tree like data structure, each node is mapped to a closure recursively and the top node behavior can be constructed from these behaviors.
So this is quite good fit for functional programming language.
Often there are a but none standard interpretation between compiler and interpreter from none computer science oriented people.
for latter, interpreter mean tree traversing program, i.e, it take program(tree) as input and return some result.
The compiler mean it return some closure(function) from input program(tree), and no specific result is not yet given. the result can be only available by applying the function some context.
so if in compiler, we don't have to traverse program many times for different program inputs. just compile once and get function, and the different values can be obtained by just applying the function with different input values. in this function evaluation, no tree node data used.
for instance, a very simple compiler program will be as following:
typedef Object Code(RContext ctx);In fact, Dart does not support overloading, so this will use overriding of methods(even if it supports overloading, this overriding approach is better though).
class AddNode implements INode {
INode node1;
INode node2;
Code compile(Context ctx) {
Code c1 = node1.compile(ctx);
Code c2 = node2.compile(ctx)
return (RContext rctx)=>(add(c1(rctx), c2(rctx)));
}
var addNode = new AddNode(new IntNode(1), new IntNode(2));
Context ctx = new Context();
Code code = addNode.compile(ctx);
RContext rctx = new RContext();
var v1 = code(ctx);
Subsequently the metaphor is changed in object oriented way, i.e, a node object has a compile method which generates a compiled closure.
This is actually a good example of usefulness of mixing two object oriented approach and functional approach.(although it became a matter of course nowadays for javascript programmers, but early days in 80's, many people were not much interested in such impure approach. Probably their target application(e.g, 5th generation Hardware) were different. but from pragmatic programming point of view, this should have been more emphasized. Some Lisp dialects were actually advocated these things, but Lisp had too poor syntax to be accepted by normal people, so there were no impact for general programmers.
------------
There were bit of digression, but bottom line is Dart will assist to write such compiler like application in wide range.
These are the reason to have appropriate syntax to express a conceptual idea directly in a language without any technical transformation(see anonymous object in Java). I remember Gosling called Java as functional language since it supports anonymous object. I thought what a silly statement it was..
Also functional approach has also very good fit with asynchronous programming.
Since we need to generate a function which will be called later time. So this requires to generate a functions from combining other functions to be executed in later time. (many Stream program depend on then method, which is essentially Future to Future function.)
Asynchronous approach and Compilation can be also combined further to have a distributed compiler at fine grained level. This will be discussed in another post.
No comments:
Post a Comment