Functional programming kind of screws itself when it comes to "implementing" modern good IDEs; the aversion to state makes it difficult to implement good tree-incremental error resistant parsing and type checking that is usable in a language aware editor.
I've developed plenty of advanced IDE infrastructure; e.g. see
The trick was abondoning FRP-style declarative state abstractions (which was my previous research topic) and moving onto something that could manage state in more flexible ways (as we say, by managing times and side effects instead of avoiding them). And once you nailed the state problem, incremental parsing, type checking, and rich editing are actually easy problems.
Yeah, incremental parsing is quite anti-functional--but tree editors don't need to parse.
Type checking I am less convinced. With syntax-directed methods one should be able to hash-n-cache each sub expression and get incremental for free. In the case of syntax directed + passing hints down the tree, just keep track of the hints too. [...let's not talk about Damas-Milner. :)]
Then, which I think Unison goes for, there is the approach where one never has untyped syntax to begin with. Not sure how annoying this is with normal programming, but should be great for theorem proving, which probably where tree editors will shine the most anyways.
We agree incremental use of global type inference algorithms is non-function.
But I am also saying you don't need to do that. Certainly don't need type-inference in the case where the ASTs are typed by construction. And the syntax directed algorithms can also infer somewhat.
You can also alternatively cache the result of global inference, which sucks for refactoring but preserves purity.
You will need type inference if you want any sort of non local communication...e.g. variables that hold different values or functions. But ya, if your language is just pure trees with no names or symbol tabkes, you don't need it; not very useful, however.
I replaced it with glitch. It was actually something I started developing for the scala IDE a long time ago that had to integrate easily with scalac, so it had to handle the limited set of effects performed by it (they no longer use this in the scala plugin, but initial results were promising, and being very incremental dealt with scalac's performance problems).
I've refined the technique over the last 7 years, you can read about it in a conference paper:
You can think of Glitch as being like React with dependency tracing (no world diffing) and support for state (effects are logged, must be commutative to support replay, and are rolled back when no longer executed by a replay).
I've developed plenty of advanced IDE infrastructure; e.g. see
http://research.microsoft.com/en-us/people/smcdirm/managedti... and http://research.microsoft.com/en-us/projects/liveprogramming...
The trick was abondoning FRP-style declarative state abstractions (which was my previous research topic) and moving onto something that could manage state in more flexible ways (as we say, by managing times and side effects instead of avoiding them). And once you nailed the state problem, incremental parsing, type checking, and rich editing are actually easy problems.