4 ms·
OCaml does objects and subtyping, while still managing to remain quite fast. http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-objects.html http://caml.inria.fr/pub
by mietek 14y ago
OCaml does objects and subtyping, while still managing to remain quite fast.
http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-objects.html http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-objects.html
- bad_user 14y agoOCaml doesn't have Haskell's type-classes or Scala's implicits. Scala's subtyping is also nominative (versus structural) and it's basically impossible to do type-inference for nominative subtyping. Whether this is good or bad, the fact remains that Scala runs on top of the JVM while Ocaml doesn't. If you ever work with Ocaml you'll notice that the type-inference system breaks down when you're working with OOP and in Ocaml you're really dealing with 2 type-systems shoved in the same language. What Ocaml does really well, compared to both Haskell and Scala is type-inference, but it's kind of a weak language IMHO as far as functional programming is concerned. I also don't get all this complaining, because in practice Scala compilation speed is not a problem. After working with Scala in production for a couple of months now, I'm beginning to suspect that all this is just hyperbole perpetuated by people that never worked with Scala a single day in their lives.
- yummyfajitas 14y agoIn practice (I write Scala every day) compilation speed is a problem. I just recompiled a work projec, just under 28kloc. 124 seconds is a problem. Admittedly, we do make heavy use of the type system.
- eeperson 14y agoOut of curiosity, how much of a problem is it? Is incremental compilation noticeably slow or is it just the full compile?
- yummyfajitas 14y agoIt's friction in the development process. Incremental compilation suffers from the fragile base class problem. In a well structured app with proper encapsulation and rigid (and type annotated) interfaces, it helps a lot.
- bad_user 14y agoThe reason for why it hasn't been a problem for us is because we've been making heavy usage of SBT's support for sub-projects. Scala makes it easier than other languages to decouple components, so after a while you begin to spot possible sub-projects all over the place. The project I'm working on right now is about 15kloc, but it's split in 3 sub-projects. Coupled with incremental (and continuous) compilation, this compilation speed issue hasn't been a problem for me. Also, if you look around, many open-source projects built with Scala follow the same technique. It's quite sane too.
- felipehummel 14y agoHow many times you do full recompile during a day? I'm curious because in my workflow I rarely do full recompile.
- yummyfajitas 14y agoIf your project isn't properly encapsulated, incremental recompilation will often come close to a full recompile, or at least recompilation of a big chunk of code. For example, if you delete AbstractFooBase.unusedMethod, sbt will recompile every file everywhere that references a concrete Foo instance. (In principle it should only need to recompile files which reference unusedMethod, but it's not that smart yet.)
- mietek 14y agoWhen I last evaluated Scala, I found the following: * Launching the interpreter takes 10 seconds; 50 times slower than Haskell. * Compiling a small module takes 15 seconds; 10 times slower than Haskell. * Running 100 command-line unit tests on a small compiled module takes 1.5 minutes; 100 times slower than Haskell. I also found Scala's type system requires many type annotations even in trivial code. For example, here Scala fails to infer the type of `optBar`, apparently because `None` is also a type: scala> class Foo { | def setBar(bar: Int) = optBar = Some(bar) | def getBar = optBar.get | var optBar = None | } <console>:8: error: type mismatch; found : Some[Int] required: object None def setBar(bar: Int) = optBar = Some(bar) ^ Workaround: scala> class Foo { | def setBar(bar: Int) = optBar = Some(bar) | def getBar = optBar.get | var optBar: Option[Int] = None | } defined class Foo Moreover, Scala's implicits can pose a significant barrier to understanding other people's code. While OCaml's type system may not integrate objects cleanly, in everyday use type annotations are not necessary, perhaps because objects aren't commonly used. Similarly, while it's possible to confuse Haskell's type inference by using advanced language extensions, in everyday use one tends not to run into such problems.
- bad_user 14y ago> Launching the interpreter takes 10 seconds With SBT you're only going to do that once per work session. Plus the startup time isn't as bad as you make it sound. I've had a much more painful experience with Ruby (Rails). > Compiling a small module takes 15 seconds That hasn't been my experience. I just did a test for a project of mine and it took 5 seconds. Without line-counts such metrics are useless (how small is that module anyway?). Also many Scala projects are composed of multiple subprojects that are efficiently managed by SBT, so a root compile triggers compilation for all these sub-modules, but context-switching between them is what increases compilation cost. > Running 100 command-line unit tests on a small compiled module When in the world are you ever going to do that? Like seriously? > Scala fails to infer the type of `optBar` In practice it's good to annotate the signature of public functions. Haskell developers do that too, because really, when a developer looks at the definition of "optBar" are you seriously going to suggest that they should be looking at other parts of the code to infer what it returns? IMHO, this is a feature, as what you want is even worse than what you get with a dynamic language, but YMMV. > Scala's implicits can pose a significant barrier to understanding other people's code I haven't met a single library or project of significant size that isn't making use of implicits in one form or another. Whether they are called global state, singletons or parameters injected through DI, we are really talking about implicit parameters. The difference is that Scala gives you the means to document these implicits in the signature (referential transparency FTW). They are also statically type-safe, can be overridden and have the extra benefit that they make possible some powerful techniques, like type-classes, something that Ocaml isn't capable of.