Readit News logoReadit News
lihaoyi · 5 years ago
> it's a high-level language with static types, so easy to make large scale changes as we figure out what the language/product was

> you mostly model data with sum types, which in my mind are the best way to model data

>it's very similar to the language I wanted to build (in particular, we could reuse built-in immutable data structures for Dark's values)

> it had a reputation for being high-performance, which meant that we could write an interpreter for Dark and not have it be terribly slow (vs writing an interpreter in python, which might be too slow)

> We have struggled to make editor tooling work for us.

> Lack of libraries

> Multicore is coming Any Day Now™, and while this wasn't a huge deal for us, it was annoying.

> we also use ReasonML

> lazyness and pure functional-ness I felt were not great

> I plan to leave keep the frontend in ReasonML

You want a statically typed functional (but not pure) language with sum types, immutable data structures, good performance, editor/IDE support, a broad library ecosystem, multithreading, a C-like syntax (I assume, since you're using ReasonML), and a nice compile-to-Javascript experience to run in the browser.

I don't want to sound too much like a fanboy, but all this really sounds like Scala. You want Scala.

yunyu · 5 years ago
Scala.js generates significantly larger bundles than Rescript — because Ocaml's semantics map more closely to those of JS, the runtime dependencies are smaller and there's a lot of tricks to minimize indirection/overhead. Additionally, interop with npm modules is much less painful with Rescript and bindings for popular third party libraries are more mature. Ignoring the merits of Scala-the-language, there are very good reasons to pick Rescript over the Scala.js toolchain.

Compare https://rescript-lang.org/docs/manual/latest/shared-data-typ... with how Scala.js represents arrays and records.

sjrd · 5 years ago
In the small, Rescript generates smaller code than Scala.js, that is true. It is mostly a question of the interdependencies in the standard Scala collection library, though, not so much the semantics of the language. And Scala.js also has its share of "tricks" (aka optimizations) to reduce indirections and overhead.

Regarding interop and the link you posted, here is the equivalent documentation page in Scala.js: https://www.scala-js.org/doc/interoperability/types.html

Yes, Rescript has more built-in types that map straightforwardly, but that is at the cost of some correctness. For example, using a JavaScript array means that JavaScript can resize it under your feet. Using `undefined` to represent `None` means that you cannot tell the difference between `None` and `Some(None)`. It's a fine trade-off to make. Scala.js happens to make the other trade-off, and offers separate types for JavaScript interop.

I like the concepts and design of Rescript, really. It's very interesting because they have all the essential requirements right (IMO) like comprehensive JavaScript interop, while making all the opposite design decisions on nonessential trade-offs compared to Scala.js.

JackMorgan · 5 years ago
Rather why not F#, which has all of that but with a fast compiler and is just a superset of OCaml
trevyn · 5 years ago
And, indeed, F#, per the followup article: https://blog.darklang.com/new-backend-fsharp/
vmchale · 5 years ago
Doesn't it have fewer features?
ghayes · 5 years ago
I'da wagered dollars to doughnuts you were going to say Rust. I believe Rust hits each of those topics head-on, as well.
amelius · 5 years ago
Rust doesn't work well as a purely functional language. You'd be constantly fighting the type checker for memory issues. (Or otherwise, why doesn't Haskell take the same route as Rust and ditch its garbage collector?)
X6S1x6Okd1st · 5 years ago
If only there was a recently published high quality book that could walk them through Scala with some hands on examples

:)

natchy · 5 years ago
this? https://www.handsonscala.com/table-of-contents.html

You the author or something? I'm actually learning F# and OCaml and am interested in Scala as well.

Tommah · 5 years ago
There is a library called py.ml [0] that lets you call Python code from OCaml. That should let you use Google Cloud's Python SDK from OCaml, although things could get unwieldy if you have to call back and forth constantly. I think it's at least worth a try, especially if the alternative is rewriting your whole codebase in Python.

[0] - https://opam.ocaml.org/packages/pyml/

dj_mc_merlin · 5 years ago
> When you're searching for product-market fit, you do the simplest, easiest thing. If you lack a good SDK for your cloud provider, the simplest, easiest thing is often a terrible architectural choice.

I understand his point here. Spending week(s) writing a good SDK is hard to justify, but if you're building new infrastructure to support a project in a more obscure language, you kinda have to sacrifice time building said infrastructure well. When Naughty Dog programmed their games in GOOL/GOAL they built their own compilers, debuggers etc. - not a trivial task.

zeckalpha · 5 years ago
They are already writing their own compiler anyway, albeit with a limited focus (initially). Perhaps they’ll eventually get Dark on Dark.
anonu · 5 years ago
The first negative sentiment OCaml post on HN that I see. Nice to see some perspective every now and then.
snazz · 5 years ago
Content on HN about the holy trinity of programming languages, text editors, and operating systems generally favors less popular options with more mystique. Anything about Java is probably going to be largely neutral or negative, while a piece on Common Lisp might be much more positive, even though Java is a far more successful programming language in most ways.

I don't think that this bias is a bad thing. It's nice to read about cool technologies that you might not use in your day job. But anyone using HN to decide on the right tool for a project should carefully consider other sources of information as well.

AnimalMuppet · 5 years ago
Assume for the moment that all languages are equal. (They aren't, but ignore that for the moment.) If you say something good about Java, there are a lot of people here who have used Java, and some of them have bad impressions that they came to through some pain.

But if you say that Common Lisp is great, there are fewer people who have really used it, so fewer people who have used it and didn't like it. And since fewer people got into it unless they really wanted to, it's easier to say "You didn't really understand it, then, or you would have liked it." The number of people who can say "No, I really got it, and I still didn't like it" is relatively small.

So far, that's just demographics. But then you get into the language itself. Java isn't an exciting language. It's not fun. It's kind of corporate and bland. There aren't many people who are really enthusiastic about Java - nor does Java give them reason to be.

nine_k · 5 years ago
But leaving OCaml for F# is a bit like leaving Scheme for Common Lisp. Most of the underlying ideas are largely the same.

Moving from OCaml to C++ or Go would be a drastic and surprising change, but it's not nearly like that.

pbiggar · 5 years ago
OP here. I don't mean this to be negative, this is just my ongoing developer blog to keep the Dark community appraised about what's going on.

There's some really great stuff about OCaml. I don't think we could have gotten through the first 2 years without OCaml, we repeatedly made very large scale changes to what our product was and how it worked, and that would have been 10x harder in something else.

I actually think OCaml stands to be in a great place in the next few years with the work being done by core community members. See https://twitter.com/patricoferris/status/1323330884515356672.

mholub · 5 years ago
so if you already had experience with Rust/etc, why did you decide to choose OCaml?

Also why not to choose F#/Mono (and now .NET core) for example?

justatdotin · 5 years ago
thanks for sharing, I find this really informative.
xfer · 5 years ago
Expecting open source developers to write a well-tested proprietary SDK for a vendor is going to be hard ask. If you need that and unwilling to do/fund the work yourself, just stick with vendor supported languages.
pdimitar · 5 years ago
I would turn this around. As a guy who was doing OSS here and there (and still got burned out by doing only a little) I completely sympathize that nobody should ever expect people to do important work for free. Absolutely.

At the same time, it's a good response when somebody muses in a saddened manner "I wish my favourite language was more popular". Then I can spring out of the bush and tell them why it isn't. This doesn't mean I expect the OSS community around the language to serve me -- of course not! But it's a good explanation on why language X isn't more commercially popular.

higerordermap · 5 years ago
I want to see more negative sentiment rust and go posts.
wk_end · 5 years ago
I used OCaml for several years professionally. It's a phenomenal language in many ways, but there's no way I'd seriously consider using it for a new project at this point.

I don't really agree on the "Learnability" and "Minor annoyances" sections here. In terms of overly academic discourse, well, everyone's experiences differ but that's simply not a problem I've personally seen in the community (and I'd happily tell you other languages have that problem in spades). In terms of learnability: Ocaml, (the good parts) is an extremely straightforward language in most respects. The tutorials on the Ocaml website are enough to get you up and running, and Real World Ocaml is freely available and it's great. It'd be nice if v2 ever came out, but...well. Between those two, if you're still struggling, give me a call and I'd be happy to tutor you :)

The rest of this article hits most of the nails right on the head. The library support just isn't there, the community is too fragmented (why is stdlib vs. Core vs. Batteries and Async vs. Lwt still an issue?), the tooling is still too rough. OCaml's lack of multicore isn't actually a problem for most use-cases, but the fact that it's been in limbo for a decade despite the endless clamouring for it tells you something about what you're hitching your wagon to.

Twenty years ago OCaml would've been a no-brainer. At this point if I wanted a practical garbage-collected language I'd choose Scala and get a large and active community, as many Java libraries as there are stars in the sky, and the most sophisticated runtime environment mankind has ever dreamed of (for better or worse). If I truly need a compiled language, well...tragically, I've been bitten by the Rust bug (to the extent that I'm starting to believe its rigid approach to ownership helps engineer better code - that the ability to freely and thoughtlessly sharing references to objects the way garbage collection grants makes it a mistake, but that's a story for another post). And if I need 100% of the power and safety types can give me, Haskell is there waiting, with a better ecosystem to boot. Everything OCaml does well other languages do better, and then some. It's an also-ran now.

ernst_klim · 5 years ago
> I'd choose Scala and get a large and active community, as many Java libraries as there are stars in the sky, and the most sophisticated runtime environment mankind has ever dreamed of (for better or worse).

Hahahaha oh wow. You never ever used Scala, aren't you? I did, I moved from OCaml to Scala.

Oh, good luck joining Scala community then, we don't have aforementioned problems, don't we? Because Akka vs Zio vs Cats vs Scalaz is not a thing. Because ensime vs metals debacle never happened. Because we don't rewrite the complete ecosystem each couple of years.

> most sophisticated runtime environment mankind has ever dreamed of

Which you need to tune quite a lot to fit Scala into it (hopefully, it's very tuneable). Oh, and this "most sophisticated runtime" doesn't support TCO btw.

Oh, and any AnyRef value (so anything but basic types) can be null, thanks, runtime.

I love Scala, but all these "I wouldn't choose OCaml, I would choose F#/Clojure/Scala/other obscure language" usually mean "I've tried ocaml but didn't try other obscure language, so maybe it's better"

I love OCaml is well, and most of your points could be reduced to simply "it's lacking manpower" (Scala is lacking it too).

Because all of the "why is stdlib vs. Core vs. Batteries and Async vs. Lwt still an issue" we have in C, C++ and many other popular languages too, but it's not a big issue. People complain on meson/cmake/autotools/boost/glib/qt but not leave for some reason.

Maybe people don't use OCaml that much rather because there are simply too few jobs and too few programmers and it's a simple chicken and egg problem. And all these technical rationalization is not the reason because it's applicable to quite a lot of languages (safe for lack of libraries)

pdimitar · 5 years ago
Yep, I completely get the "the grass is NOT greener on the other side" sentiment. I've been a victim of it many times and I am much more careful these days.

> I love OCaml is well, and most of your points could be reduced to simply "it's lacking manpower" (Scala is lacking it too).

For the better or the worse, this is literally the #1 priority one has to have before trying to technically evaluate a language / framework these days. Otherwise you get sucked on a joyful ride at the end of which you find lack of employability. :(

I personally much prefer OCaml's syntax but since Rust has much more mindshare and is mostly serving the same niche (with GC being the apples-to-oranges comparison here), I preferred to work with Rust. I still would like to work with OCaml but the odds are stacked against the financial incentives of doing so.

> Because all of the "why is stdlib vs. Core vs. Batteries and Async vs. Lwt still an issue" we have in C, C++ and many other popular languages too, but it's not a big issue. People complain on meson/cmake/autotools/boost/glib/qt but not leave for some reason.

Sure, many other languages suffer from that but it's still a very good ideal to strive for -- namely have very few (ideally one) ways of doing things. I personally look for such languages / frameworks and sadly they are very few and far between (Elixir and Clojure come to mind as refreshing exceptions and even they don't follow it everywhere).

---

In the end, we all do this for money. If I could work without charging for it then I'd likely know more languages and even work more overall, but it's not the reality we are living in currently.

darksaints · 5 years ago
So...I think a decent choice to make here is to switch from OCaml to F#. You'll get almost all of the benefits and most of the drawbacks go away. And for the most part, you can directly translate the code from OCaml to F#.

The big reason to not use F# vs OCaml tends to come down to the lack of functors... but it looks like your current codebase might not be using them much.

banashark · 5 years ago
I enjoy f# a lot, but it doesn't necessarily help with all of their problems.

One of the biggest problems they mention is with postgres. F# has a postgres problem as well.

Your options in f# for postgres usage include the following high-level categories:

• Dapper/RepoDb/Other community libs

• Typeprovider based like Fsharp.Data.Npgsql

• EF core (where you build the fsharp design-time support yourself)

• Using C# in another project as a database interaction abstraction

I've had to mix and match for the projects I've worked on because I've had trouble finding a single library where:

1) Joins are supported in a sane way

2) Batch inserts work

3) Interacting with native features (views, functions, SET variables) works

4) It's still in fsharp

It's not bad, but when I work on $DAYJOB projects in Typescript/etc where database access is smooth, I wonder how long it might take to rewrite for the database heavy projects.

Also should mention that I'm very thankful for the libraries that _do_ exist, and the effort put into making them as feature as they are. It's just one of the areas that I don't think is a strength of F# right now.

akra · 5 years ago
I've done quite a bit of F# Postgres in a previous life and I didn't find it much different than other programming languages. However I tend to just use the Npgsql library directly with ADO.NET for performance which I often needed for my cases with Postgres. These days you can insert array objects, insert whole objects graphs, do batch inserts and create little helpers to read/write sets with Npgsql/PSQL directly; often much faster than using a higher level ORM. In my experience Postgres often would produce query plans that required a lot of SQL tuning/rewriting in a different way to get right (e.g. loose index scan SQL to get latest entry per group). I just wrap the solution/build with DB tests to make sure the SQL is covered well vs using the type provider. Tbh the amount of code (in lines) is mostly the same as well to do it vs a higher level framework - we did the comparison.
to11mtm · 5 years ago
Have you looked into Linq2Db [0]? (I'm a contributor to the project) I know a few F# users have had success with a couple of minor caveats. I can say it handles most of the points you mentioned fairly well however (Great join syntax, lots of bulk insert options, easy wire-in for native features.)

[0] - https://github.com/linq2db/linq2db/

JaggerJo · 5 years ago
We've been using https://github.com/Zaid-Ajaj/Npgsql.FSharp and it's great. Uses well supported lib behind the covers and just provides a small layer on top.

Same thing exists from MS SQL https://github.com/Zaid-Ajaj/DustyTables , also great.

Used both in prod. No regrets and wouldn't wan't something else. Also involves zero magic - just raw SQL and a nice functional API.

darksaints · 5 years ago
But those are all database abstraction mechanisms or ORMs. Regular SQL access to postgres databases is pretty much a fully solved problem in F#, even if the ORMs are not.
tamrix · 5 years ago
If you're writing a while platform with a new ide concept, built in deployment and your own framework on top. (darklang) I think an ORM is the least of their problems.

They'll not going to pick F# because they're in competition with Azure.

They don't want ocaml because of marketability. It's technically the right choice and direction but the learning curve for developers is turning them off the platform as a whole.

siwatanejo · 5 years ago
maybe you should give this one a try: https://github.com/rspeele/Rezoom.SQL
loxs · 5 years ago
I tried doing that for my program and failed miserably, mostly because CLR is not optimised the same way the OCaml runtime is optimised to minimise copying of memory. As a result the (direct translation of the) program became more than 5 times slower, which was a deal breaker for this use case.

Yes, there are ways to write it in a .NET-y way in F#, but then it requires a "complete" rewrite and F# gives no real benefits with "being similar".

In contrast, after that I migrated to Rust and I am delighted. I wrote about it here: https://news.ycombinator.com/item?id=24893285

Of course, this is also a full-rewrite without using the same idioms as in OCaml (mostly because I mutate objects directly when needed) but I still think it's much better than F# as the language (Rust) is miles ahead in the practicality domain. Indeed, it's much better than anything I've seen so far. And still so very much "functional" and "elegant". I just miss the transparent currying from OCaml.

ernst_klim · 5 years ago
> You'll get almost all of the benefits and most of the drawbacks go away.

That's a bit overstatement. You can call .Net code from F#, just like you can call Java from Clojure or Python/Rust/C from OCaml.

It just would be foreign and unidiomatic (hello, null pointers, methods, OOP).

And you can call C/Python/Rust from OCaml, we made quite a lot of wrappers for Gstreamer and some Rust libs in OCaml and it was quite painless.

So it's a bit of simplification, you can call foreign code in OCaml, it's not that much harder than F# considering there are higher level FFIs for C, Rust and Python available. Author could just use these as well.

dfgdghdf · 5 years ago
Writing an F# wrapper for a C# API is considerably less involved than writing an OCaml wrapper for a C API.

This is because F# and C# share:

* build tools

* package management

* garbage collector

* base types (string, int, etc).

The F# type-checker understands C# types, so you know that you are consuming the C# API correctly (at least at the type-level). F# can be be used as a new syntax for C#, if you wanted to go that way.

angio · 5 years ago
I was thinking the same all throughout the reading. I've been using F# on GCP in production for 3 years now and it's fantastic and only getting better. You can leverage existing .NET libraries (for example, you get official GCP libraries from google) and if you use them enough it's easy enough to write a functional wrapper around them. I recently rewrote the frontend using Fable.React so that I can share code between backend and frontend.
Nuzzerino · 5 years ago
> The big reason to not use F# vs OCaml tends to come down to the lack of functors...

What do you mean by that? F# has support for functors, or are you referring to something else? https://fsprojects.github.io/FSharpPlus/applicative-functors...

darksaints · 5 years ago
Those are an implementation of functors as they exist in Haskell. The functors I'm talking about are actually a language level construct that is a primary abstraction mechanism in OCaml/SML. They are essentially higher-level modules: modules that are parameterized by other modules.

https://stackoverflow.com/a/16353711

mc10 · 5 years ago
OCaml functors are not the same as Haskell/F# functors/applicatives (which are essentially one and the same in OCaml if you use named arguments).

Instead, they're roughly "functions from modules to modules": https://dev.realworldocaml.org/functors.html. Functors allow you to replicate much of what classes/objects in an OO language offer, but with static instead of dynamic dispatch.

tikhonj · 5 years ago
In OCaml, "functors" are parametrized modules—mostly unrelated to functors and applicatives in the Haskell sense. Think about it as a module that can take another module as an input.
karmakaze · 5 years ago
I was thinking the same thing. Using multicores and having a library ecosystem (through interop rather than conventional F#) should be a win. I don't have an idea what performance difference to expect but certainly closer to OCaml than Python even for single-core.
darksaints · 5 years ago
At least as of a couple years ago, OCaml wins on performance for anything single core, but not by much. F# is usually within a 5-10% performance gap. Absolutely better than Python.
ksec · 5 years ago
I wonder if anyone has built a list of functions, libraries and toolings that are considered as essential among mature Programming Languages. Not the core features but ecosystem around it.

So that when people are evaluating a PL, they can known immediately what is missing. And people wanting to make a new PL knows what is missing in their ecosystem, the community can jump in to help.

k__ · 5 years ago
"OCaml folks talk about Fancy Type System problems, instead of how to actually build products and applications"

I had the impression that's a general problem with FP.

giantDinosaur · 5 years ago
Mostly due to interest in FP being driven by intrinsic desire to use it, since it's so rare in enterprise. Anyway, a lot of that discussion filters down into more popular languages, so it's pretty incorrect to think of it as all academic junk or something.

Deleted Comment

sweeneyrod · 5 years ago
It is much less of a problem with OCaml than most non-OCaml users would expect. OCaml isn't Haskell; if you want for loops and similar generic imperative features you can have them!
k__ · 5 years ago
I know and it could very well be that most of the FP crowd I talked to were Haskell/PureScript/Nix/Dhall proponents.

OCaml/ReScript/Clojure people seem to be a bit more chill.

dimitrios1 · 5 years ago
Save for Erlang and Elixir, this tends to be the case with ML-family FP languages, not so much with LISPs, in my opinion of course.
wilsonthewhale · 5 years ago
agreed. Clojure is probably the most pragmatic FP language in the space.
nautilus12 · 5 years ago
The problem is there is no middle ground. FP people forget about the product because of FP. Alot of non-FP people forget also forget about their product because their are swamped with unecessary maintanence. There is a middle road in there somewhere where you use just enough FP to avoid the problems you would face without it, without getting totally sucked into making it perfectly consistent.
fulafel · 5 years ago
From my experience in Clojure projects and watching Erlang/Elixir projects, it's not like this at all in those cultures.
fulafel · 5 years ago
You've been misimpressed :) Clojure/ClojureScript, Elm, Erlang/Elixir are examples of pragmatic communities and cultures.