Cheap and Secure Web Hosting Provider : See Now

[Solved]: Is it possible to write an HTML compiler with no mutable state?

, , No Comments
Problem Detail: 

That's probably a vague question but allow me to try and give an example:

My compiler does transformations on HTML (from HTML to HTML). It scans a flattened DOM tree, and relies on lookbehinds (on elements pushed onto a stack) to decide what transformation to apply. I can give more detail if necessary but I don't want to lose the reader.

Can such logic be alternatively implemented with no mutable state? I have become a big believer in functional programming and have made it a point to make my code as functional-style as possible. I don't like loops that perform actions based on the content of a previous iteration, by saving the information from a previous iteration in stacks or booleans. I need to augment the functionality of this routine and will probably tip the code from being "just about understandable" to "only the author will understand this, everyone else don't touch".

But I have little background in compiler theory & development so am wondering if the problem domain necessitates mutable state in practice.

Asked By : Sridhar-Sarnobat

Answered By : o11c

In theory, any program can be treated as functional by treating every operation as "replace the world with a world this piece of state replaced by a different value". In practice ... this actually works pretty well.

Your code will look something like:

root_node = parse_html()  for each operation:     root_node = root_node.replace_using_operation(operation) 

For a leaf or node that you know won't be affected by this operation, replace_using_operation looks like:

fn replace_using_operation(self, op):     return self 

For the typical non-leaf case, replace_using_operation will look like:

fn replace_using_operation(self, op):     children = new List<Node>();     # pedantically, this is not "functional", but realistically it is.     # if your language has generators or a iterator map function you can     # make it purely functional, but most people find this easier to read.     for each ch in self.children:         children.append(ch.replace_using_operation(op))     new_self = new Node(children)     delete self     return new_self 

Of course, depending on what knowledge you have of the operation, you might want to perform different operations on some children. Also note that you're perfectly free to pass additional arguments (including snapshots of other branches of the tree - just remember you don't own them) or to have entirely separate replace_* functions instead of passing operation as an argument.

This code is only a very rough skeleton, after all.

Best Answer from StackOverflow

Question Source :

3.2K people like this

 Download Related Notes/Documents


Post a Comment

Let us know your responses and feedback