Readit News logoReadit News
noelwelsh · 4 months ago
I saw a talk by someone from Google about their experiences using Rust in the Android team. Two points stuck out: they migrated many projects from Python, so performance can't have been that much of a concern, and in their surveys the features people liked most were basics like pattern matching and ADTs. My conclusion is that for a lot of tasks the benefit from Rust came from ML cicra 1990, not lifetimes etc. I feel if OCaml had got its act together around about 2010 with multicore and a few other annoyances[1] it could have been Rust. Unfortunately it fell into the gap between what academia could justify working on and what industry was willing to do.

[1]: Practically speaking, the 31-bit Ints are annoying if you're trying to do any bit bashing, but aesthetically the double semicolons are an abomination and irk me far more.

nine_k · 4 months ago
I'd say that Google strives to have a reasonably short list of languages approved for production-touching code. Rust can replace / complement C++, while OCaml cannot (it could replace Go instead... fat chance!). So I suspect that the team picked Rust because it was the only blessed language with ADTs, not because they won't like something with faster compile times.

No way OCaml could have stolen the Rust's thunder: we have a number of very decent and performant GC-based languages, from Go to Haskell; we only had one bare-metal-worthy expressive language in 2010, C++, and it was pretty terrible (still is, but before C++11 and C++17 it was even more terrible).

GhosT078 · 4 months ago
In 2010, Ada 2005 was the most bare-metal-worthy expressive language. Now that would be Ada 2022.
hardwaregeek · 4 months ago
Wouldn’t Kotlin be a more reasonable choice in that case? It has ADTs and a lot of the same niceties of Rust.

Deleted Comment

StopDisinfo910 · 4 months ago
> I feel if OCaml had got its act together around about 2010 with multicore and a few other annoyances[1]

OCaml had its act together. It was significantly nicer than Python when I used it professionally in 2010. Just look at what JaneStreet achieved with it.

The main impediment to OCaml was always that it was not American nor mainly developed from the US.

People like to believe there is some technical merit to language popularity but the reality it’s all fashion based. Rust is popular because they did a ton of outreach. They used to pay someone full time to mostly toot their horn.

jvican · 4 months ago
Hear, hear. This theory also explains why other languages such as Scala were never really mainstream despite allowing Java- and Kotlin- style programming and having a much broader follower base in Europe. Lack of outreach, concerted marketing, and advocacy from American companies that have always dominated the narrative.
nothrabannosir · 4 months ago
Python, PHP, Ruby: all not American though, right? Do you mean those only got hockey stick growth when they happened to get picked up by the USA ? But then couldn’t the same have happened for ocaml? And if so: why didn’t it, as it supposedly did for the others

Not to mention Linux I guess

IshKebab · 4 months ago
I agree. If OCaml had solved some of its bigger paper cuts it could have been a real player. Compilation time is much better than Rust too:

* OPAM is quite buggy and extremely confusing.

* Windows support is very bad. If you ever tried to use Perl on Windows back in the day... it's worse than that.

* Documentation is terse to the point of uselessness.

* The syntax style is quite hard to mentally parse and also not very recoverable. If you miss some word or character the error can be "the second half of the file has a syntax error". Not very fun. Rust's more traditional syntax is much easier to deal with.

Rust basically has none of those issues. Really the only advantage I can see with OCaml today is compile time, which is important, but it's definitely not important enough to make me want to use OCaml.

jll29 · 4 months ago
I'd say the Modula-2 inspired module system is a very valuable asset compared to today's Rust.

The only contact with OCaml I had was that I wrote a bug report to a university professor because I wanted his tool to process one of my files, but the file was larger than OCaml's int type could handle. That itself wasn't the problem - he wrote it wasn't straight forward to fix it. (This is a bug of the type "couldn't have happened in Common LISP". But I guess even in C one could replace int by FILE_SIYE_TYPE and #define it as unsigned size_t, for instance).

pjmlp · 4 months ago
That is why if I feel like doing ML style programing I rather reach out for Kotlin, Scala or F# than Rust, and even then Java and C# have gotten enough inspiration that I can also feel at home while using them.

I am no strage to ML type systems, my first one was Caml Light, OCaml was still known as Objective Caml, and Mirada was still something being discussed on programming language lectures on my university.

From what I see, I also kind of find the same, too many people rush out for Rust thinking that ML type systems is something new introduced by Rust, without having the background where all comes from.

michaelcampbell · 4 months ago
> too many people rush out for Rust

Yes

> thinking that ML type systems is something new introduced by Rust

This feels off to me. Of the hype-train that Rust has been for a while now, a _type_ of type system it has hasn't been any of the cars, as it were.

At least in my readings; I'm sure we travel in different circles, but even the few academic oriented things have been other language features and memory safety through and through.

gerdesj · 4 months ago
"I feel if OCaml had got its act together ..."

The great thing is we have choice. We have a huge number of ways to express ideas and ... do them!

I might draw a parallel with the number of spoken languages extent in the UK (only ~65M people). You are probably familiar with English. There are rather a lot more languages here. Irish, Scottish, Welsh - these are the thriving Brythonic languages (and they probably have some sub-types). Cornish formally died out in the sixties (the last two sisters that spoke it natively, passed away) but it has been revived by some locals and given that living people who could communicate with relos with first hand experience, I think we can count that a language that is largely saved. Cumbric ... counting still used by shepherds - something like: yan, tan, tithera toe.

I am looking at OCAML because I'm the next generation to worry about genealogy in my family and my uncle has picked Geneweb to store the data, taking over from TMG - a Windows app. His database contains roughly 140,000 individuals. Geneweb is programmed in OCAML.

If you think that programming languages are complicated ... have a go at genealogy. You will soon discover something called GEDCOM and then you will weep!

DrewADesign · 4 months ago
For personal projects? Sure. In nearly any development organization larger than one person, unilaterally deciding to use OCAML instead of what everybody else uses would go over about as well as unilaterally deciding to use Aramaic at meetings.
Akronymus · 4 months ago
From the gedcom wiki page it doesnt seem that bad. At least the data format itself. But it seems like its very easy to screw up working with it.
beezlewax · 4 months ago
It's weird to see someone from the UK champion the Irish language as a choice as if they didn't try to systematically wipe it from the face of the earth for quite a long period of time.

Choice is good of course so do keep up the good work.

unstruktured · 4 months ago
There is absolutely no reason to use double semicolons in practice. The only place you really should see it is when using the repl.
sigzero · 4 months ago
Yeah, it makes me think he doesn't understand them in OCaml.
munificent · 4 months ago
> I feel if OCaml had got its act together around about 2010 with multicore and a few other annoyances[1] it could have been Rust.

Arguably, that could have been Scala and for a while it seemed like it would be Scala but then it kind of just... didn't.

I suspect some of that was that the programming style of some high profile Scala packages really alienated people by pushing the type system and operator overloading much farther than necessary.

whimsicalism · 4 months ago
Scala was always going to be hamstrung by the fact that it's a JVM language and yes, the crazy stuff people did with the language didn't help.
yodsanklai · 4 months ago
> aesthetically the double semicolons are an abomination and irk me far more.

I think they have been optional for like 20 years, except in the top-level interactive environment to force execution.

That being said, I still don't get why people are so much upset with the syntax. You'll integrate it after a week writing OCaml code.

swiftcoder · 4 months ago
Erlang faces a similar uphill battle when it comes to syntax - there are three different punctuation marks used as terminators depending on context, and you have to keep in your head the rules for all 3. As someone who has written quite a bit of Erlang, but infrequently, it's always a battle.

And I think a big part of the reason that Elixir has done so well (Elixir pretty much starting out as Erlang-but-with-Ruby-syntax)

whimsicalism · 4 months ago
I spent more than a week writing ocaml and still found the syntax pretty annoying. ReasonML would have been nice if the Ocaml community actually cared, but they are a bit insular.
shpongled · 4 months ago
As someone who loves SML/OCaml and has written primarily Rust over the past ~10 years, I totally agree - I use it as a modern and ergonomic ML with best-in-class tooling, libraries, and performance. Lifetimes are cool, and I use them when needed, but they aren't the reason I use Rust at all. I would use Rust with a GC instead of lifetimes too.
hawk_ · 4 months ago
How do you use Rust without lifetimes?
troupo · 4 months ago
OCaml also needed the brief but bright ReasonML moment to add/fix/improve some of the syntax IIRC and work on user-friendly error messages. But this should've definitely happened much much earlier than it did.
Taikonerd · 4 months ago
I would say ReasonML also needed more follow-through. It seems like the OCaml community hasn't really rallied behind it.
77pt77 · 4 months ago
> I feel if OCaml had got its act together around about 2010 with multicore and a few other annoyances[1] it could have been Rust

That's about the time-frame where I got into OCaml so I followed this up close.

The biggest hindrance in my opinion is/was boxed types.

Too much overhead for low level stuff, although there was a guy from oxbridge doing GL stuff with it.

debugnik · 4 months ago
That's still the biggest hindrance in my opinion, at least for my use cases. OxCaml, Jane Street's fork, has some features for unboxed types and stack-based allocation of boxed types; hopefully it goes upstream.
ezst · 4 months ago
I feel that whatever "OCaml - the good parts" might be, it lives through Scala today. It's syntactically familiar/pleasing, it deals equally well with your high throughput (JVM), low-footprint (scala-native), web (scala-js/scala-wasm), small script to large monolith needs equally well, and its tooling/community support is orders of magnitude better than the other functional-first "popular" languages (OCaml, Haskell, Clojure, …).

Deleted Comment

the__alchemist · 4 months ago
I'm with you. I think some of the nicest parts of rust have nothing to do with memory safety; they're ways to structure your program as you mention.
garbthetill · 4 months ago
doesnt rust still have the advantage of having no gc? I dont like writing rust, but the selling point of being able to write performative code with memory safety guarantees has always stuck with me
noelwelsh · 4 months ago
I think "no gc but memory safe" is what originally got people excited about Rust. It's a genuinely new capability in production ready languages. However, I think Rust is used in many contexts where a GC is just fine and working with lifetimes makes many programs more painful to write. I think for many programs the approach taken by Oxidized OCaml[1] or Scala[2] gives 80% of the benefit while being a lot more ergonomic to work with.

When I see Rust topping the "most loved language" on Stack Overflow etc. what I think is really happening is that people are using a "modern" language for the first time. I consistently see people gushing about, e.g., pattern matching in Rust. I agree pattern matching is awesome, but it is also not at all novel if you are a PL nerd. It's just that most commercial languages are crap from a PL nerd point of view.

So I think "no gc but memory safe" is what got people to look at Rust, but it's 1990s ML (ADTs, pattern matching, etc.) that keeps them there.

[1]: https://github.com/oxcaml/oxcaml

[2]: https://docs.scala-lang.org/scala3/reference/experimental/cc...

inkyoto · 4 months ago
OCaml was[0] very popular in the high-frequency trade programming, especially because of its high performance and predictable latency despite having a garbage collector, plus, of course, because of the correctness of the code written in it.

OCaml's GC design is a pretty simple one: two heaps, one for short-lived objects and another one for the long-lived objects, and it is a generational and mostly non-moving design. Another thing that helps tremendously is the fact that OCaml is a functional programming language[1], which means that, since values are never mutated, most GC objects are short or very short-lived and never hit the other heap reserved for the long-lived objects, and the short-lived objects perish often and do so quickly.

So, to recap, OCaml’s GC is tuned for simplicity, predictable short pauses, and easy interoperability, whereas Java’s GC is tuned for maximum throughput and large-scale heap management with sophisticated concurrency and compaction.

[0] Maybe it still is – I am not sure.

[1] It is actually a multiparadigm design, although most code written in OCaml is functional in its style.

vips7L · 4 months ago
You can write safe and performative code with a garbage collector. They're not mutually exclusive. It just depends on your latency and throughput requirements.
0cf8612b2e1e · 4 months ago
Considering how many applications are running in JS/Python execution speed or GC is a low concern for many programs. Ergonomics (community, compiler guarantees, distribution, memory pressure, talent availability, whatever) seem more meaningful.
rtpg · 4 months ago
I think people like ADTs and pattern matching that Rust gives, but really the way that Rust becomes even more pleasant is that you have _so many_ trait methods on standard library objects that offer succinct answers to common patterns.

Haskell of course has some of this, but immutability means that Haskell doesn't have to have answers for lots of things. And you want pattern matching as your basic building block, but at the end of the day most of your code won't have pattern matching and will instead rely on higher level patterns (that can build off of ADTs providing some degree of certainty on totality etc)

ubercore · 4 months ago
I've only forayed into rust a bit, but I agree. I would happily take a language like Rust that sacrifices some speed for simpler semantics around ownership/lifetimes.

Just Arc, clone and panic your way to success! :)

omcnoe · 4 months ago
The issue regarding academia is that functional programming is treated as an afterthought/sideshow that is mainly of interest for research. Almost no-one is teaching FP concepts to undergrads.
uncircle · 4 months ago
Before 2010-something, the very popular meme in software engineering was that functional programming is really hard to understand, and really not suited for anything outside of academia. [1] Now that I've been programming in an immutable functional language for almost a decade (Elixir), I'm certain the meme was mostly born out of unfamiliarity [2] than actual complexity; it's really not that much different than imperative, just requires a different approach and understanding of the trade-offs. Writing a distributed system (say, a web app backend) in an imperative, mutable language in this day and age is increasingly a laughable proposition in my view. Use the right tool for the problem at hand.

Many academically-trained developers never got exposed to FP in school, and to this day you can still hear, albeit in much lesser numbers thanks to the popularity of Elixir/Clojure/etc., the meme of FP being "hard" perpetuated.

---

1: I would go so far as to blame Haskell for the misplaced belief that FP means overcomplicated type theory when all you want is a for loop and a mutable data-structure.

2: I played with OCaml 10+ years ago, and couldn't make head or tails of it. I tried again recently, and it just felt familiar and quite obvious.

pjmlp · 4 months ago
I can assure you that wasn't the case on my degree, if anything almost every lecture had its own programming language.

Maybe I got lucky being in one of the most relevant universities in Portugal, however I can tell that others in the country strive for similar quality for their graduates, even almost 40 years later.

le-mark · 4 months ago
The way ocaml mashes the object syntax into sml was always most annoying to me. It was also pretty weak on the systems programming side (threads, sockets, signals, fork) 20-30 years ago iirc. That’s probably changed by now. Multi core; not many runtimes handle this today so that’s not much of a hindrance IME.
fulafel · 4 months ago
Anyone have a link to the Android talk? I wonder if it was backend code or on-device code. On device you could probably justify the compromises of a no-GC language better.
noelwelsh · 4 months ago
I tracked it down: https://www.youtube.com/watch?v=QrrH2lcl9ew

I don't think it was on-device code, as they talked about porting Python projects. But you can watch the talk to see if I'm misremembering.

lmm · 4 months ago
> I feel if OCaml had got its act together around about 2010 with multicore and a few other annoyances[1] it could have been Rust.

No, that wouldn't have made the difference. No-one didn't pick up OCaml because it didn't have multicore or they were annoyed by the semicolons.

People don't switch languages because the new language is "old language but better". They switch languages because a) new language does some unique thing that the old language didn't do, even if the unique thing is useless and irrelevant, b) new language has a bigger number than old language on benchmarks, even if the benchmark is irrelevant to your use case, or c) new language claims to have great interop with old language, even if this is a lie.

There is no way OCaml could have succeeded in the pop culture that is programming language popularity. Yes, all of the actual reasons to use Rust apply just as much to OCaml and if our industry operated on technical merit we would have migrated to OCaml decades ago. But it doesn't so we didn't.

brabel · 4 months ago
I appreciate both OCaml and Rust, but your view seems to be entirely wrong to me, sorry to be blunt.

People wouldn't care much for Rust at all if it didn't offer two things that are an absolute killer feature (that OCaml does not have):

* no GC, while being memory safe.

* high performance on par with C while offering no-cost high level conveniences.

There's no other language to this day that offers anything like that. Rust really is unique in this area, as far as I know.

The fact that it also has a very good package manager and was initially backed by a big, trusted company, Mozzila, while OCaml comes from a Research Lab, also makes this particular race a no-brainer unless you're into Functional Programming (which has never been very popular, no matter the language).

sanderjd · 4 months ago
Yeah I was initially drawn to rust because I loved ocaml but wished it were more practical.

Dead Comment

birdfood · 4 months ago
OCaml is probably my favourite language.

The most involved project I did with it was a CRUD app for organising Writer's Festivals.

The app was 100% OCaml (ReasonML so I could get JSX) + Dream + HTMX + DataTables. I used modules to get reusable front end templates. I loved being able to make a change to one of my data models and have the compiler tell me almost instantly where the change broke the front end. The main value of the app was getting data out of excel into a structured database, but I was also able to provide templated and branded itineraries in .odt format, create in memory zipped downloads so that I didn't need to touch the server disk. I was really impressed by how much I could achieve with the ecosystem.

But having to write all my database queries in strings and then marshal the data through types was tiring (and effectively not compile time type checked) and I had to roll my own auth. I often felt like I was having to work on things that were not core to the product I was trying to build.

I've spent a few years bouncing around different languages and I think my take away is that there is no perfect language. They all suck in their own special way.

Now I'm building an app just for me and I'm using Rails. Pretty much everything I've wanted to reach for has a good default answer. I really feel like I'm focused on what is relevant to the product I'm building and I'm thinking about things unrelated to language like design layout and actually shipping the thing.

BenGosub · 4 months ago
What is the idiomatic way to handle the results from the database in a strongly typed functional language?
birdfood · 4 months ago
I certainly can’t say whether this is idiomatic as I was working it all out myself. But I’d basically write a type for each operation (as I’d read elsewhere). And honestly this was a bit of a drag too. I really wanted some reflection to make generating this code more ergonomic. From memory I’d have types like these

Author id: int, name: string, book_id: int

NewAuthor name: string, book_id: int

ViewAuthor name: string, book_title: string

Author represents the data in the db, NewAuthor allows for an insert operation, and ViewAuthor is for showing the data to a user.

You could argue for combing Author and NewAuthor and making id optional but I wanted to enforce at the type level that I was working with stored data without needing to check id everywhere.

_mu · 4 months ago
I haven't worked in OCaml but I have worked a bit in F# and found it to be a pleasant experience.

One thing I am wondering about in the age of LLMs is if we should all take a harder look at functional languages again. My thought is that if FP languages like OCaml / Haskell / etc. let us compress a lot of information into a small amount of text, then that's better for the context window.

Possibly we might be able to put much denser programs into the model and one-shot larger changes than is achievable in languages like Java / C# / Ruby / etc?

jappgar · 4 months ago
That was my optimistic take before I started working on a large Haskell code base.

Aside from the obvious problem that there's not enough FP in the training corpus, it seems like terser languages don't work all that well with LLMs.

My guess is that verbosity actually helps the generation self-correct... if it predicts some "bad" tokens it can pivot more easily and still produce working code.

sshine · 4 months ago
> terser languages don't work all that well with LLMs

I’d believe that, but I haven’t tried enough yet. It seems to be doing quite well with jq. I wonder how its APL fares.

When Claude generates Haskell code, I constantly want to reduce it. Doing that is a very mechanical process; I wonder if giving an agent a linter would give better results than overloading it all to the LLM.

yawaramin · 4 months ago
There's actually a significant difference between Haskell and OCaml here so we can't lump them together. OCaml is a significantly simpler, and moderately more verbose, language than Haskell. That helps LLMs when they do codegen.
b_e_n_t_o_n · 4 months ago
This has been my experience as well. Ai writes Go better than any language besides maybe html and JavaScript/python.
gf000 · 4 months ago
My completely non-objective experiment of writing a simple CLI game in C++ and Haskell shows that the lines of code were indeed less in case of Haskell.. but the number of words were roughly the same, meaning the Haskell code just "wider" instead of "higher".

And then I didn't even make this "experiment" with Java or another managed, more imperative language which could have shed some weight due to not caring about manual memory management.

So not sure how much truth is in there - I think it differs based on the given program: some lend itself better for an imperative style, others prefer a more functional one.

QuadmasterXLII · 4 months ago
My experience is that width is faster than height to type- mostly from lack of time spent indenting. This is _completely_ fixed by using a decent auto-formatter, but at least for me the bias towards width lingers on, because it took me years to notice that I needed an auto-formatter
Buttons840 · 4 months ago
If LLMs get a little better at writing code, we might want to use really powerful type systems and effect systems to limit what they can do and ensure it is correct.

For instance, dependent types allow us to say something like "this function will return a sorted list", or even "this function will return a valid Sudoku solution", and these things will be checked at compile time--again, at compile time.

Combine this with an effect system and we can suddenly say things like "this function will return a valid Sudoku solution, and it will not access the network or filesystem", and then you let the LLM run wild. You don't even have to review the LLM output, if it produces code that compiles, you know it works, and you know it doesn't access the network or filesystem.

Of course, if LLMs get a lot better, they can probably just do all this in Python just as well, but if they only get a little better, then we might want to build better deterministic systems around the unreliable LLMs to make them reliable.

gylterud · 4 months ago
The day when LLMs generate useful code with dependent types! That would be awesome!
dkarl · 4 months ago
In Scala, I've had excellent luck using LLMs to speed up development when I'm using cats-effect, an effects library.

My experience in the past with something like cats-effect has been that there are straightforward things that aren't obvious, and if you haven't been using it recently, and maybe even if you've been using it but haven't solved a similar problem recently, you can get stuck trawling through the docs squinting at type signatures looking for what turns out to be, in hindsight, an elegant and simple solution. LLMs have vastly reduced this kind of friction. I just ask, "In cats-effect, how do I...?" and 80% of the time the answer gets me immediately unstuck. The other 20% of the time I provide clarifying context or ask a different LLM.

I haven't done enough maintenance coding yet to know if this will radically shift my view of the cost/benefit of functional programming with effects, but I'm very excited. Writing cats-effect code has always been satisfying and frustrating in equal measure, and so far, I'm getting the confidence and correctness with a fraction of the frustration.

I haven't unleashed Claude Code on any cats-effect code yet. I'm curious to see how well it will do.

gylterud · 4 months ago
I have found that Haskell has two good things going for it when it comes to LLM code generation. Both have to do with correctness.

The expressive type system catches a lot of mistakes, and the fact that they are compile errors which can be fed right into the LLM again means that incorrect code is caught early.

The second is property based testing. With it I have had the LLM generate amazingly efficient, correct code, by iteratively making it more and more efficient – running quickcheck on each pass. The LLM is not super good at writing the tests, but if you add some yourself, you quickly root out any mistakes in the generated code.

akoboldfrying · 4 months ago
Property-based testing is available in other languages. E.g., JS has fast-check, inspired by quickcheck.
omcnoe · 4 months ago
I think that functional languages do actually have some advantages when it comes to LLM's, but not due to terseness.

Rather, immutability/purity is a huge advantage because it plays better with the small context window of LLM's. An LLM then doesn't have to worry about side effects or mutable references to data outside the scope currently being considered.

sshine · 4 months ago
> My thought is that if FP languages like OCaml / Haskell / etc. let us compress a lot of information into a small amount of text, then that's better for the context window.

Claude Code’s Haskell style is very verbose; if-then-elsey, lots of nested case-ofs, do-blocks at multiple levels of intension, very little naming things at top-level.

Given a sample of a simple API client, and a request to do the same but for another API, it did very well.

I concluded that I just have more opinions about Haskell than Java or Rust. If it doesn’t look nice, why even bother with Haskell.

I reckon that you could seed it with style examples that take up very little context space. Also, remind it to not enable language pragmas per file when they’re already in .cabal, and similar.

esafak · 4 months ago
I think LLMs benefit from training examples, static typing, and an LSP implementation more than terseness.
nextos · 4 months ago
Exactly. My experience building a system that generates Dafny and Liquid Haskell is that you can get much further than with a language that is limited to dynamic or simple static types.
nukifw · 4 months ago
To be completely honest, I currently only use LLMs to assist me in writing documentation (and translating articles), but I know that other people are looking into it: https://anil.recoil.org/wiki?t=%23projects
d4mi3n · 4 months ago
I think this is putting the cart before the horse. Programs are generally harder to read than they are to write, so optimizing for concise output to benefit the tool at the potential expense of the human isn't a trade I'd personally make.

Granted, this may just be an argument for being more comfortable reading/writing code in a particular style, but even without the advantages of LLMs adoption of functional paradigms and tools has been a struggle.

seprov · 4 months ago
Procedures can be much more concise in functional/ML syntax, but many things are not -- dependency injection in languages like C# for example are able to be much less verbose because of really excellent DI libraries and (arguably more sane) instance constructor syntax.
pmahoney · 4 months ago
I tried to like OCaml for a few years. The things that hold me back the most are niggling things that are largely solved in more "modern" langs, the biggest being the inability to "print" arbitrary objects.

There are ppx things that can automatically derive "to string" functions, but it's a bit of effort to set up, it's not as nice to use as what's available in Rust, and it can't handle things like Set and Map types without extra work, e.g. [1] (from 2021 so situation may have changed).

Compare to golang, where you can just use "%v" and related format strings to print nearly anything with zero effort.

[1] https://discuss.ocaml.org/t/ppx-deriving-implementation-for-...

throwaway127482 · 4 months ago
Go's %v leaves a lot to be desired, even when using %+#v to print even more info. I wish there was a format string to deeply traverse into pointers. Currently I have to import go-spew for that, which is a huge annoyance.

Python does it best from what I've seen so far, with its __repr__ method.

jerf · 4 months ago
The default %v does leave some to be desired, but don't underestimate the utility of being able to shove anything at it and get something back. This is especially important because this applies recursively; you can have a structure that may have something "unprintable" buried deeply in it, but at least it won't prevent you from printing everything else.

Strongly-typed languages that do not force any sort of stringification on values, and thus refuse to compile if you try to dump a simple log message of one of these values out, are really annoying to work with. I understand the conceptual purity of saying "Hey, maybe not everything even has a string representation" but it makes debugging a real pain. If I were writing a new language today I think I'd mandate that everything gets a default debugging string output by default because the alternative is just so rough.

Even a not-great printer that may have a sort of "*unprintable*" bailout, or print something not terribly useful, but doesn't actually stop you from printing anything, is better than a language that completely rejects it at compile time.

tucnak · 4 months ago
Go has both Stringer and GoStringer interfaces, which is basically the same thing as __repr__.
JaggerJo · 4 months ago
DarkLang which was initially written in OCaml eventually switched to F#. From what I remember the main reasons were the library ecosystem and concurrency.

I'm know .NET in and out, so I might be biased. Most of the boring parts have multiple good solutions that I can pick from. I don't have to spend time on things that are not essential to the problem I actually want to solve.

I've used F# professionally for multiple years and maintain a quite popular UI library written in it. But even with .NET there still are gaps because of the smaller F# language ecosystem. Not everything "just works" between CLR languages - sometimes it's a bit more complicated.

The main point I'm trying to make is that going off the beaten path (C#) for example also comes with a cost. That cost might or might not be offset by the more expressive language. It's important to know this so you are not surprised by it.

With OCaml it's similar I'd say. You get a really powerful language, but you're off the beaten path. Sure, there are a few companies using it in production - but their use case might be different than yours. On Jane Streets Threads and Signals podcast they often talk about their really specific use cases.

1: https://blog.darklang.com/new-backend-fsharp/

garbthetill · 4 months ago
What a brilliant article, it really puts to rest for me, the whole “why not use F#?” argument. In almost every OCaml thread, someone suggests F# as a way to sidestep OCaml’s tooling.

I’ve always been curious about OCaml, especially since some people call it “Go with types” and I’m not a fan of writing Rust. But I’m still not sold on OCaml as a whole, its evangelists just don’t win me over the way the Erlang, Ruby, Rust, or Zig folks do. I just cant see the vision

debugnik · 4 months ago
Funny, I moved to OCaml to sidestep F# tooling. At least last time I used F#: Slow compiler, increasingly C#-only ecosystem, weak and undocumented MSBuild (writing custom tasks would otherwise be nice!), Ionide crashes, Fantomas is unsound...

But OCaml sadly can't replace F# for all my use cases. F# does get access to many performance-oriented features that the CLR supports and OCaml simply can't, such as value-types. Maybe OxCaml can fix that long term, but I'm currently missing a performant ML-like with a simple toolchain.

JaggerJo · 4 months ago
Did you try F# in JetBrains Rider? It's the best F# tooling you can buy IMO.
joshmarlow · 4 months ago
It's been a few years since I've touched OCaml - the ecosystem just wasn't what I wanted - but the core language is still my favorite.

And the best way I can describe why is that my code generally ends up with a few heavy functions that do too much; I can fix it once I notice it, but that's the direction my code tends to go in.

In my OCaml code, I would look for the big function and... just not find it. No single workhorse that does a lot - for some reason it was just easier for me to write good code.

Now I do Rust for side projects because I like the type system - but I would prefer OCaml.

I keep meaning to checkout F# though for all of these reasons.

loxs · 4 months ago
I migrated from OCaml to Rust around 2020, haven't looked back. Although Rust is quite a lot less elegant and has some unpleasant deficiencies (lambdas, closures, currying)... and I end up having to close one one eye sometimes and clone some large data-structure to make my life easier... But regardless, its huge ecosystem and great tooling allows me to build things comparatively so easily, that OCaml has no chance. As a bonus, the end result is seriously faster - I know because I rewrote one of my projects and for some time I had feature parity between the OCaml and Rust versions.

Nevertheless, I have fond memories of OCaml and a great amount of respect for the language design. Haven't checked on it since, probably should. I hope part of the problems have been solved.

jasperry · 4 months ago
Your comment makes me think the kind of people who favor OCaml over Rust wouldn't necessarily value a huge ecosystem or the most advanced tooling. They're the kind who value the elegance aspect above almost all else, and prefer to build things from the ground up, using no more than a handful of libraries and a very basic build procedure.
loxs · 4 months ago
Yeah, I was that kind of person, then I wrote a real tool that does real work in OCaml... and then I discovered than I am no longer such a person and went to Rust.
ackfoobar · 4 months ago
> the end result is seriously faster

Do you have a ballpark value of how much faster Rust is? Also I wonder if OxCaml will be roughly as fast with less effort.

loxs · 4 months ago
Just the straight/naive rewrite was ~3 times faster for my benchmark (which was running the program on the real dataset) and then I went down the rabbit hole and optimized it further and ended up ~5 times faster. Then slapped Rayon on top and got another ~2-3x depending on the number of cores and disk speed (the problem wasn't embarrassingly parallel, but still got a nice speedup).

Of course, all of this was mostly unneeded, but I just wanted to find out what am I getting myself into, and I was very happy with the result. My move to Rust was mostly not because of speed, but I still needed a fast language (where OCaml qualifies). This was also before the days of multicore OCaml, so nowadays it would matter even less.

Deleted Comment

javcasas · 4 months ago
Were you using the ocamlopt compiler? By default, ocaml runs in a VM, but few people figure that out because it is not screaming its name all the time like a pokemon (looking at you JVM/CLR). But ocaml can be compiled to machine code with significant performance improvements.
debugnik · 4 months ago
> By default, ocaml runs in a VM,

The Dune build system does default to ocamlopt nowadays, although maybe not back around 2020.

loxs · 4 months ago
Yeah, I just checked in my repository, it was ocamlopt
shortrounddev2 · 4 months ago
OCaml is a great language without great tooling. Desperately needs a good LSP implementation to run breakpoints and other debugging tools on VSCode or other LSP-aware IDEs. I know there ARE tools available but there isn't great support for them and they don't work well
debugnik · 4 months ago
LSP isn't the protocol that interfaces with debuggers, that'd be DAP. You're right that OCaml debugging is kinda clunky at the moment.

OCaml does have an okay LSP implementation though, and it's getting better; certainly more stable than F#'s in my experience, since that comparison is coming up a lot in this comment section.

StopDisinfo910 · 4 months ago
What’s clunky about the Ocaml debugger?

Ocaml has been shipping with an actual fully functional reverse debugger for ages.

Is the issue mostly integration with the debugging ui of VS Code?

nukifw · 4 months ago
Indeed, efforts should be made in terms of DAP (https://microsoft.github.io/debug-adapter-protocol//), extending the following experimentation: https://lambdafoo.com/posts/2024-03-25-ocaml-debugging-with-.... However, I find the assertion about tooling a bit exaggerated, don't you?
lambda_foo · 4 months ago
Using DAP with VSCode and OCaml's bytecode debugger (https://github.com/hackwaly/ocamlearlybird) works reasonably well already. My blog post above can be modified to work with VSCode, but I'm primarily an Emacs user. The main issue with Emacs and DAP is the DAP modes are not very polished.

The missing piece for OCaml is debugging native code, the compiler doesn't emit enough DWARF information and debuggers like LLDB or GDB, need to be modified to understand OCaml's DWARF information. Even there DAP with LLDB/GDB works, it's just the debugger doesn't have enough information to work well. You end up working with debugging assembly or C (if it's parts of the runtime). I've written up a PR documenting native debugging here https://github.com/ocaml/ocaml/pull/13747.

dismalaf · 4 months ago
?? OCaml has had a completion engine for as long as I can remember (definitely over a decade) and it powers their LSP these days. I do know however that the community focuses mostly on Vim and Emacs.