11 ms·
Why ML/OCaml are good for writing compilers (1998)
- kod 11y agoDespite being almost 20 years old, the only thing about this that sounds anachronistic is extolling the virtues of exceptions failing at runtime.
- GreaterFool 11y agoEvery time I see ML on HN I hope it's about ML the language and I'm sad when it turns out to be Machine Learning instead, haha. It's a shame ML-family of languages isn't very popular. 1ML for instance could be a fantastic modern language but I don't see that happening.
- LukeHoersten 11y agoSame here. ML-family languages are my favorite. Haskell seems to be the most popular though I may be biased considering I consider myself a Haskeller.
- carterschonwald 11y agoI think there's some room for a next Gen language somewhere between the two.
- sdegutis 11y agoBetween OCaml and Haskell, I would definitely pick Haskell. Even if only because I much prefer Haskell's typeclass system to OCaml's modules. That said, I use Clojure and would choose Clojure over either Haskell or OCaml, because of the live code-reload abilities Clojure comes with, which makes it really great for rapid development. And because Clojure emphasizes immutability so much, it's trivial to keep only the state around that you want to keep, and refresh the rest. I don't think I would be nearly as fast without that.
- loup-vaillant 11y agoMy window manager is Xmonad, and restarting it after a configuration change does feel like hot code swapping: since the configuration file is actually Haskell code, it gets recompiled. The Yi editor has similar capabilities. I think hot code swapping has less to do with the language, and more to do with whatever surrounds it.
- sdegutis 11y agoThat makes sense in the context of a window manager, because the processes live outside it, meaning it has very little to no state of its own. But when developing a web app, you have to login to it every time you reload the code, because being signed in is in-memory state.
- damncabbage 11y ago> ... being signed in is in-memory state. Can be in-memory state. Everything beyond toy-sized I've ever worked on has externalised this sort of state to a database of some kind, if only so you can run a second copy for the sake of failover. I don't believe your example is relevant.
- paulddraper 11y agoOr used a signed assertion that is verified with a secret.
- loup-vaillant 11y ago> meaning it has very little to no state of its own That's false. Windows are affected to workspaces. They are sorted in a particular order (set by the user as they move the windows). Each workspace uses a particular layout. One particular window on each workspace last had focus. There's a "current workspace" pointer. That's a bit more than "very little to no state". All of that is preserved upon reload. And I bet my hat all that state was in-memory. Then there is Yi, a text editor. There's no avoiding lots of in-memory state in there. Live code reload in Haskell. It's real.
- adrusi 11y agoWhat is 1ML, I've never heard of it and it's hard to google.
- GreaterFool 11y agoAfter typing 1ml into Google the paper is the first result and the link header sums it up nicely "1ML - core and modules united" :P
- Avshalom 11y agoAh, see ddg give me a lot of people asking yahoo questions about converting things to milliliters. Completely forgot to check Google.
- riscy 11y ago1ML is basically SML with first-class modules. It's very recent research (paper appeared in ICFP 15) so I'm not surprised there isn't much coming up. EDIT: I'd like to add that the video from ICFP is up: https://www.youtube.com/watch?v=42Wn-mXWcms https://www.youtube.com/watch?v=42Wn-mXWcms
- david-given 11y agoIs there a compiler for it yet?
- riscy 11y agoonly a prototype interpreter [1]. this stuff is fresh out of the research lab [1] http://www.mpi-sws.org/~rossberg/1ml/ http://www.mpi-sws.org/~rossberg/1ml/
- david-given 11y agoCan't make it build, unfortunately: ocamlopt -c lib.ml File "lib.ml", line 24, characters 49-58: Error: Unbound value List.mapi TBF, this is probably a good thing; it's not like I have any time...
- mamcx 11y agoF#? I think is doing better than expected. Is the one I'm using now, and is nice.
- nickpeterson 11y agoIt's puzzling to me that it isn't more popular honestly. My main exposure is through F#, but I would be interested in a new dialect or revision to ML, especially if it gained reasonable community support (the size of say, Scala or Clojure).
- saosebastiao 11y agoMy dream language would be 1ML with a co-effect system as described by Tomas Petricek (pretty big in the F# community, but unfortunately his research isn't being incorporated into F#). But yeah, unless some company goes into full sponsorship mode, ML will always be on the niche side.
- riscy 11y agoJane Street is a major user/sponsor of Ocaml.
- saosebastiao 11y agoI would call them a major user, but sponsor not so much. Their investments in the ocaml ecosystem have mostly been self serving...driven by what they need, not what the ocaml community as a whole needs. Contrast this with Sun/Java, Microsoft/DotNET, Google/Go, etc., where development is happening on what developers everywhere are looking for.
- yminsky 11y agoActually, we've funded lots of things that we don't directly use. For example, we funded the development of OPAM, which we don't use internally at all. Moreover, the funding of OCaml Labs was aimed broadly at improving the OCaml ecosystem, rather than just addressing our narrow internal needs. Our work and funding on compiler improvements like Flambda is aimed at things we want, but they're also of broad utility to the users of the language. Merlin is another example of something we've supported that is useful to us internally, but also useful more broadly. This is of course self serving in the sense that we think the OCaml ecosystem is important to our future, and so we want to help it flourish. But it's a relatively enlightened form of self interest...
- saosebastiao 11y agoThat's fair, I wasn't aware that OPAM was funded by JS. It is definitely one of the better package managers that I've worked with too. I'd like to ask you a question, as it isn't every day that yminsky responds to me. If you knew from the beginning that you would end up creating an entire ecosystem (including libraries, package managers, etc) mostly from scratch, would you have chosen SML instead? I know when you joined JS that OCaml was probably the pragmatic choice. But so many ML enthusiasts (myself included) prefer the syntax and semantics of SML and end up using OCaml/F#/Scala because the SML ecosystem is so non-existent.
- sdegutis 11y agoPersonally, I really like the ideas that OCaml brings, but I feel like it comes with too many compromises in consistency of the language. So I have to ask myself: if I'm going to make compromises, which ones would I make? At the end of the day it usually comes down to choosing between a new language, and one that I already know pretty well, and the benefit of using what I already know is pretty strong.
- kruhft 11y agoA (classic?) book on writing compilers with ML: http://www.amazon.com/Compiling-Continuations-Andrew-W-Appel/dp/052103311X http://www.amazon.com/Compiling-Continuations-Andrew-W-Appel...
- MaxScheiber 11y agoIn my experience, #4 has held up extremely well over time and is the most compelling reason for choosing an ML over another language. Algebraic data types are an absolute joy to work with when dealing with abstract syntax trees. The other points are obviously great to have, but strong language support for ADTs is key, in my opinion. I'm not certain I agree with #3. It seems to defeat the purpose of a strong type system. Either way, it can be very nice to express meta-level constructs in a matching object-level type. For example, if the language you are writing a compiler for has an int32 datatype, but you use an int64 in the language you're writing the compiler in, you'll need to simulate overflow. It would just be easier and safer to use an int32 in both places. These days, I'd recommend Menhir over ocamlyacc unless you have a very specific use case that the former breaks on but the latter works on.
- wtetzner 11y ago> In my experience, #4 has held up extremely well over time and is the most compelling reason for choosing an ML over another language. I have a hard time choosing between ADTs and the module system, honestly. If I really had to chose, I'd probably pick ADTs, but it'd be very close. It's really disappointing every time a new language comes out and it has a weak module system. Especially F#, which was primarily influenced by OCaml.
- BruceIV 11y agoA thousand times this; I've been working on compiler-y things in C++ for the past couple years, and I am firmly convinced that the visitor pattern is a truly inadequate way to attempt to compensate for the lack of a proper destructuring pattern-matching construct in a language.
- baldfat 11y agoI went through the videos of a coursera class for Programming Languages with Dan Grossman. https://www.coursera.org/course/proglang https://www.coursera.org/course/proglang He starts teaching programming with ML and then moves to Racket and ends with Ruby. I had tried to teach myself Haskell several times but it always fell flat. I ended up loving ML and Racket (Especially Racket) the 1ML does look very interesting. Racket is pretty amazing for me. I learned a ton and was able to really improve my code in Python and R.
- sklogic 11y agoMLs are way much better than the average blubs for writing compilers, but yet they still have some issues. The worst is the amount of a boilerplate code needed to implement even the smallest pass over an AST. Say, you want to visit and rewrite all the identifier nodes, but yet you must implement recursive functions for all the node types. In Haskell a bit of the Scap Your Boilerplate magic relieves this problem a bit, but still a long way to go to reach a level of convenience of Nanopass. Next issue is related: slightly amended AST types are hard to define, they cannot be derived fromtypesxisting one by a simple rewrite. Also, MLs do not allow an easy way to handle metadata transparently. What I really want to have is ML type system and Nanopass density combined in one language (working on it, not done yet).
- rwmj 11y agoYou can usually generate the visitor function, if your ML has a decent macro language (as does OCaml). I'll give you the one about amended ASTs though. I once had to write an HTML / CSS processor. It started with the HTML DOM [tree] and performed successive processing stages on it, each time adding a little bit of extra data into the tree and extra node types. I had to tediously write an html type, an html1 type, an html2 type and so on. Never did find out if there's a better way to do this.
- wtetzner 11y agoI don't know that anyone has really solved that problem: http://lambda-the-ultimate.org/node/4170 http://lambda-the-ultimate.org/node/4170 Honestly, maybe the solution is just to look at the problem a different way, and use an attribute grammar instead, like Ted Kaminski mentioned.
- jasim 11y agoAsking as a complete layperson, are there any other strongly typed languages that doesn't have this issue when parsing an AST and adding metadata during subsequent passes?
- 11y ago
- jmartinpetersen 11y agoSML is one of a very few languages that have a formal description of the meaning of the language. http://sml-family.org/sml97-defn.pdf http://sml-family.org/sml97-defn.pdf
- qznc 11y agoThis is also true for C [0,1] and other mainstream languages [2] now. [0] http://robbertkrebbers.nl/thesis.html http://robbertkrebbers.nl/thesis.html [1] https://github.com/kframework/c-semantics https://github.com/kframework/c-semantics [2] http://www.kframework.org/index.php/Projects http://www.kframework.org/index.php/Projects
- Drup 11y agoFor interested people, there is a very nice OCaml MOOC for beginners currently: https://www.france-universite-numerique-mooc.fr/courses/parisdiderot/56002/session01/courseware/W1/ https://www.france-universite-numerique-mooc.fr/courses/pari... !
- gnuvince 11y agoI love writing compilers in OCaml: I T.A. a compiler class and my own implementation of the project (a compiler for a not-quite subset of Go) is written in OCaml. Compared to my thesis project which is written in Java, OCaml is a breath of fresh air and I feel that the single, most important feature of OCaml is its type system, especially having sum types available. Once you learn to use sum types to design your solutions, it's very hard to go back to other languages that don't support them and where you need to figure out the least painful way to emulate them.
- smcl 11y agoHey - minor long shot but have you got a link to the course? Or is it on edx/coursera?
- MaxScheiber 11y agoNot the original comment author, but I thoroughly enjoyed taking Penn's undergraduate compilers course, which used OCaml to compile a basic OO language with single inheritance and dynamic dispatch. http://www.seas.upenn.edu/~cis341 http://www.seas.upenn.edu/~cis341
- gnuvince 11y agoHi, no the course isn't on a MOOC platform. The website from last year is available here: http://cs.mcgill.ca/~cs520/2015/ http://cs.mcgill.ca/~cs520/2015/
- agumonkey 11y agoJust in case, coursera has a course where a bit more than a third is devoted to sml (sml/nj): proglang by Dan Grossman (UoWashington)
- groovy2shoes 11y agoPrevious discussion: https://news.ycombinator.com/item?id=3002838 https://news.ycombinator.com/item?id=3002838
- xvilka 11y agoOne of the main stoppers of the wider OCaml adoption, I think, is a poor Windows support. For example, missing Unicode support [1] or lack of the opam [2] on this platform. [1] https://github.com/ocaml/ocaml/pull/153 https://github.com/ocaml/ocaml/pull/153 [2] https://github.com/ocaml/opam/issues/2191 https://github.com/ocaml/opam/issues/2191
- bpyne 11y agoI used SML/NJ for a course I took last Fall. It was my first experience with ML other than looking over some sample code on the web. I'm not sure why, but my thought processes just work well with ML. Beautiful language. Very expressive while light on verbosity. I heard an interview with Benjamin Pierce in which he extolled the virtues of the OCaml compiler. While he said that many other languages are interesting to him, OCaml is the go-to for getting stuff done. Given people's comments and the linked post, my project for next Summer is going to be writing a compiler in OCaml for some simple language I'll define and implement.
- pcwalton 11y ago> ML has, perhaps, the best gc around; it's so fast that for many real apps it's as fast as the C++ malloc/free, and maybe even a little faster in some cases. You don't have to wring your hands about using ML's gc, as you do with Java's, which is slow. This is from 1998. I highly doubt this is true today. HotSpot now has an incredibly good generational, concurrent garbage collector.
- jordwalke 11y agoOther tracing collectors have certainly caught up since 1998, but I'd keep my eye on two things that have also happened since 1998: 1. Work by Damien Doligez which made further improvements to OCaml's current tracing collector (in 4.03) which further reduced pause times. 2. The multicore OCaml tracing collector work that's going on right now at Cambridge. If I understand correctly, this work involved not only partitioning memory into multiple thread local heaps, and a shared heap, but it also improved the collector in general. I haven't tested it but I'm curious if the combination of this work will again put it ahead of other alternatives.
- devit 11y agoIn the meantime, several newly designed languages do in fact have most or all of these features along with other pragmatic advantages. Rust and Scala being perhaps the most popular and maybe best ones.
- jhallenworld 11y agoThese sound like good reasons for using it for compiler front ends. Is it equally helpful compiler back ends? I mean optimization and register allocation.
- jackweirdy 11y agoWhile #8 is useful, I've been writing a static analysis tool for JS in OCaml and it's been extremely hard to refactor when type inference is happening on function parameters. Mostly because I can't easily look to see whether I've refactored a method to use my new types. But on the other hand, I think that's because (I at least get the impression) there's a different strategy for refactoring functional programs effectively. I haven't quite figured out what that is, though.
- conistonwater 11y agoActually, in Haskell the usual coding style is to explicitly declare the type of all top-level things, which kind of contradicts his first example of 8. The idea is that every time you change a type, all uses of it that use the previous type are then highlighted as compile-time errors, which is definitely useful for refactoring. I'm not sure about the example that he gives, but if used this way type inference is actually quite useful for refactoring. Plus, all intermediate non-top-level types are adjusted automatically whenever possible, which saves work — I think this is really what he's saying.