Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is awesome. Did you feel like Go is good enough for the task? I've always thought its lack of expresiveness make it very unsuitable for compilers and all kinds of pattern-matching/tree-representation-based code (opposite to e.g. Haskell/OCaml)


I'd call it average-ish at best. It's not as bad as C, but it's not as strong as Haskell, which is a high bar to meet.

However, if you write things idiomatically and use a bit of thought, it's not hopeless, either. You can write type-safe nodes with interfaces, for instance:

    type ArithExpr struct {
        Op ArithOp
        L  ArithNode
        R  ArithNode
    }
where ArithNode is definitely an interface (implemented by ArithExpr) and ArithOp may be, depending on your mood. "Pattern matching" can not be perfectly replicated, especially if you deeply match, but "run this on ArithNodes recursively" is actually not that hard to express. Invert the pattern matching into method calls; it isn't a perfect translation but it hits many of the use cases. Modest cleverness in the methods may be helpful, for instance, it may be helpful for all nodes to implement a "RunOnNodeIfArithNode" method that usually does nothing, and only works on ArithNodes, to avoid a lot of assertions and checking in the core algorithms, that sort of thing. Don't try to port a pattern-matching approach, use the native stuff you've actually got. In the end I can't promise you'd never have any type assertions, but it should be possible to write a compiler that isn't drenched in them.

Still not my first choice, though. Might prefer it over Python, though; it would certainly be more verbose but the way I'd use the strong typing would probably make up for that in safety.


Don't try to port a pattern-matching approach, use the native stuff you've actually got.

What you just said has got this old Smalltalker starting to think of pattern matching as "polymorphism on steroids." Is that what it actually is?


It bears certain similarities to multiple dispatch, as if a case statement was an inlined multiple-dispatch function, but I'd say that much as objects can theoretically be implemented with closures and closures can theoretically be implemented with objects but I don't think they're best thought of as the "same thing", polymorphism and various dispatch techniques aren't really the same thing as pattern matching.

My real point here is use what you've got; trying to use object polymorphism in Haskell would be as big a mistake there as trying to naively jam pattern matching into Go. Stick to the native idioms as much as possible. While I agree that Go's native idioms are limiting compared to some other languages I also think a lot of people grossly overestimate the limitations.


Everything in Smalltalk was pretty much polymorphism, lambdas, and reflection. I suspect that's why I like golang. (There are a few other tricks, but better not to go there unless you really know what you're doing.)


>Everything in Smalltalk was pretty much polymorphism, lambdas, and reflection. I suspect that's why I like golang.

Huh? While it has both, Go is as far from lambdas and reflection as you can go and still be modern language.


That the Visitor pattern, right?


Go's compiler is written in Go.


Which doesn't really say much about how suitable it is to write a compiler in go.

Most C compilers are written in C. I would not argue that C is a language particularly suited to writing compilers though.


That only proves it's technically possible


Go's compiler is written in Go that was automatically converted from C.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: