20 ms·
My thoughts on OCaml
- cdaringe 4y agoMy friends. Algebraic effects in ocaml 5! I did protohackers and AOC with effects and it was a blast! Im not a daily ocaml driver so my code can be a bit clunky, but i love the patterns effects unlock, especially around module coupling.
- xvilka 4y agoBuilding, LSP server, and immutability are definitely better in 2023 than author describe in their article.
- nequo 4y agoIn what sense is immutability better? What changed?
- ronnier 4y agoWhy would a company use ocaml? I’ve worked in software now for most of my life, from small to the biggest companies. I’ve watched teams with senior developers use non mainstream languages to build services and just about every time those devs get board again, leave the team, leaving them stuck with this system that’s hard to develop and different from the rest of the orgs, eventually resulting in a complete rewrite. At companies I try to be boring, not weird, and efficient. Which usually means for me, writing in a very mainstream language that is easy to hire for.
- decafninja 4y agoI'm sure some companies out there might find a competitive advantage for using exotic languages and tech stacks. But I get the impression the more common scenario is that the engineers were bored and given the chance, wanted to play with something new and shiny. It also depends on the company's prestige. A company like Jane Street using OCaml? Considering both their prestige and the amount they pay, I'm sure they will have no problems hiring. Nor will their alumni have problems getting hired elsewhere. Some no name startup or even some "innovation lab" inside a boring cludgy Fortune500? Yeah, no thanks.
- felixyz 4y agoJane Street wasn't all that prestigious when they started using OCaml. The way they put it is "it was easier to find great programmers in the empty set of people who know OCaml than in the huge set of other programmers" (roughly). So, on the contrary, I think it might help boring cludgy company find quality talent. I think there is a fallacy being repeated in this thread, namely that the choice is between mainstream and weird, or between old-and-tested and new-and-shiny. No, that's not the choice. The choice is between tools and abstractions that are helpful and productive, and those that aren't. Some of the helpful and productive things are old, some are new, some are mainstream, some are niche. I don't fully understand how someone wants to spend their career in programming and not actively seek out what is helpful and productive, rather than what currently gets the most questions on Stack Overflow or has a big pool of people who put it on their CV. It's not like all languages are equally good. It's a wasteful approach.
- decafninja 4y agoThere's another aspect, which myself and a few others in this thread have mentioned - hireability. Both from the company's and employee's perspective. I'm pretty sure Jane Street would have paid well even when they were an obscure name. Will boring cludgy Fortune500 company or noname startup pay well for someone to come use an exotic tech stack that is used very rarely at any other companies? Likely not. Likewise, would an engineer well versed in some exotic language, and can land offers at top companies, come work for a boring cludgy Fortune500 company that is only willing to pay a fraction of what they can get elsewhere? Maybe if you've already made your fortune elsewhere and well on the road to FIRE, and are really just looking for interesting work regardless of pay.
- felixyz 4y agoSo are you saying that Jane Street more or less bribed people who didn't really care for OCaml to come work in a weird language, by offering a good salary? I find that far-fetched, and there are many other examples of companies attractive highly-competent people because they choose -- no, not exotic, weird, or niche tech, but good tech, that aid people thinking more clearly and abstracting better. As in everything else, there is a trade-off involved here of course. And what is truly good and helpful is by no means obvious, and might take time to assess.
- anthk 4y agoMirageOS and microkernels.
- jlouis 4y agoA language like ocaml excels when the input and output are program-like, and the problem can't be number-crunched by hardware. The typical example would be a compiler. Other examples would be model checkers, code generators for number crunching libraries, proof assistants, and so on. Complex problems, where you need to explore different avenues of approach quickly, and where symbolic manipulation is at the heart of the problem. Thus, ocaml is best used as a "kernel" or "module". The contextual part of your system uses the part written in ocaml as a service. But ocaml doesn't excel at problems which are common to a typical company. The people who are in the intersection of wanting to solve those problems, and ocaml developers are few. The same intersection with a more mainstream language is far larger. However, if you find yourself with a problem at which ocaml excels, chances are the mainstream languages ends up falling short very quickly, because they tend to lack the abstraction features necessary for correctly handling the complexity.
- riku_iki 4y agoThe question is if modern versions of popular languages (java, c#) caught up on ocaml's syntax sugar, or maybe this syntax sugar is trivially replaceable by some utility functions. Maybe you could bring any example of such ocaml functionality?
- belmont_sup 4y agoSyntax and sugar is subjective, right? Instead, easier to discuss the layer beneath syntax, and that’s to compare the type systems. Java now has some version of sum types aka algebraic data types, but because of its beginnings, it may never feel as easy to use. And ease of use is important, as is evident from discussions here. Had to look up to see where Java is at for sum types. First link I found. https://sfietkonstantin.github.io/2021/09/03/Java-sum-type.html https://sfietkonstantin.github.io/2021/09/03/Java-sum-type.h...
- riku_iki 4y agosum types is not something supercritical, it saves few lines of code. Also, somehow I rarely have need to use something like that personally. > And ease of use is important the question is if insignificant syntax sugar worths switching to unpopular platform with undeveloped toolings and uncertain support.
- lallysingh 4y ago.. that's a complaint for all new languages. You don't know which ones will stick until you try. Code in a strongly-typed functional language is easier to maintain because of the features of the language. The functional part gives great abstraction, and the strongly-typed part gives enough structure to make the whole thing tractable.
- rashkov 4y agoAbsolutely agreed. I'm lucky to work on a ReasonML front-end codebase and the type system and immutability are a real pleasure to work with. The strong typing lets you code against the compiler, and there are many instances of "if it compiles it works" that crop up throughout development. There's no fear of refactoring code that you didn't write, because the compiler will warn you about consequences on the far end of the codebase that you didn't even know existed. As a result of all of that, the app feels very solid to use and has comparatively few runtime errors.
- giraffe_lady 4y agoVery cool to hear. I've been using rescript some recently and was hoping for exactly that sort of benefit. I have a mixed opinion of ocaml itself having used it professionally a moderate amount. But one thing I can't deny is that ocaml programs seem to "age" better than any other languages, even other strongly typed languages.
- the_af 4y ago> Why would a company use ocaml? PG claims using Lisp was the "secret sauce" to his early success. Whether this is true or not, and whether this is still true for companies today, remains to be seen. But it's an argument for things like OCaml.
- kaba0 4y agoIt won’t really answer your question, but I found the Signals & Threads podcast fantastic, and it made me appreciate OCaml much more (it is produced by someone working at Jane Street). I personally found the MirageOS, build systems and language design episodes terrific.
- yafbum 4y agoBack when I tried it, there seemed to be a few verticals where Ocaml abstractions made Ocaml very productive to work with. Once a colleague and I did a programming race between two languages, to see how long it would take to implement a small cryptanalysis program using Ocaml vs C++. I wrote it in a day, and it took my desk neighbor who was doing the same in C++ a couple of weeks. What made the difference: - There were a lot of things I didn't have to worry about. For example, I was working with nontrivial structures but didn't have to write any boilerplate functions for deep equality or lex ordering. - Immutable structures with GC made it much more direct to translate the math into a working program. Ditto with guaranteed tail recursion optimization. - The match syntax caught many issues at compile time by forcing me to reason about every case. As a result I had many less runtime bugs to deal with, while my colleague needed to troubleshoot memory and correctness issues half the time. Ymmv. This was for research and didn't end up in production use. The C++ implementation was also much "closer to the metal" so was able to wring out more performance. Still the difference in initial velocity was striking and there could've been a case that this would've been a better choice based on dev velocity in that vertical.
- substation13 4y ago> Why would a company use ocaml? Why wouldn't a company use Brainfuck?
- lmm 4y agoOCaml is pretty much the most "boring", "mainstream" language that isn't awful. It's been around for decades. It's got an established library ecosystem, development tools and all that. And pretty much every bigger/more popular language is missing one or more basic feature that's been common-sense since the late '70s (e.g. sum types or pattern matching).
- deleted 4y ago[deleted]
- nu11ptr 4y agoI like OCaml, but if I were to start a new project with an ML I'd probably lean towards F# to take advantage of all the .NET libs
- JaggerJo 4y agoWe use F# in prod. Could not be happier.
- dimitrios1 4y agoCompletely ignorant here: - I really want to do a project in an almost "pure" functional language. I tried with Elixir and Phoenix, and while they are certainly great, and I wouldn't mind using it again, Elixir, and subsequently Erlang didn't feel like FP a lot of times, it felt like the warty Elixir/Erlang way to do FP, so it didn't scratch that itch for me (but again, still a great experience overall) - is there a way to do this openly? I.E. with dotnetcore, running on linux containers, no windows what so ever, etc? Guessing yes but wanted to make sure from people who have actually done it - What exactly about the .NET libraries that has everyone so hyped up about? I remember from my C# .NET days, they always felt to be lacking.
- victorNicollet 4y agoToday you can install the .NET runtime, as well as the .NET development tools, on both Windows and Linux. They handle F# as well as C# out of the box. You can `dotnet publish MyApp.fsproj` on either Windows or Linux, copy the resulting `publish/` folder to another machine with a different OS, and use `dotnet MyApp.dll` to run it. There are also ways to create containers, though I have never tried them for lack of an actual use case. As for libraries, .NET comes with a huge standard library, much larger than what you would find on a different language. Off the top of my head, here are a few things that come with .NET that would have been a third party library in other languages: text encodings, protocols (HTTP client, TLS, QUIC, SMTP), mainstream hashes (MD5/SHA1/SHA256), mainstream crypto (AES/DES/RSA/EC/ChaCha), serialization (JSON/ XML), weird formats (X509/ASN.1/tar/MIME), mainstream compression (deflate/brotli/zip), binary data manipulation (e.g. endianness conversion, AVX intrinsics, memory-mapping), runtime code generation, in-assembly resources, interoperability (COM, JavaScript, Objective C, SQL), concurrent collections, async... Besides, since C# is popular, many tools have .NET-compatible clients or libraries which can then be accessed from F#.
- s-zeng 4y agoA significant amount of these issues are solved by sticking to Core, Dune, and avoiding imperative blocks
- anthk 4y agoOcaml5 is multithreaded. MLdonkey would run much better. Compared to the classical Amule, a monstruosity writen in C++, at least it doesn't leak memory like some youngster with a constipation.
- 4ad 4y ago[flagged]
- sgeisenh 4y agoEspecially if modular implicits land, you get the best of both functions and typeclasses. Pretty weird way to start the post.
- wk_end 4y agoThat's a big "if". The author themselves mentions modular implicits and points out that they haven't been updated in something like five years. I don't think modular implicits are going to happen in Ocaml in our lifetimes.
- arc-in-space 4y agoSomeone mind explaining how these help? I'm unfamiliar with OCaml, but looking at the documentation of modules, I don't understand what they have to do with interfaces in the OOP sense(EDIT: or, rather, ad-hoc polymorphism), which I'm pretty sure is what the author meant.
- Errancer 4y agoThe point as I understand is that interfaces in the OOP sense try to mimic what modules do. Therefore OCaml not having them is not a serious accusation since everything you try to accomplish with interfaces / design patters you can and should be able to do with modules. Here is the article explaining the concept: https://www.pathsensitive.com/2023/03/modules-matter-most-for-masses.html https://www.pathsensitive.com/2023/03/modules-matter-most-fo... but I have to note that I never worked in OCaml so this is just my theoretical understanding.
- Verdex 4y agoTo be fair, ocaml doesn't have something exactly like c#/java interfaces. Given some problem that you might want to solve with a c#/java interface, you can also solve it with ocaml modules by flipping the coding structure on it's head. I'm not going to try to explain exactly what this looks like because I actually don't really like that structure of coding, so I don't feel like I'm going to do it justice. BUT ocaml also has row polymorphism and polymorphic invariants, which you can use to get something much directly closer to c#/java interfaces. The major difference is that with ocaml it's structural typing and with c#/java it's nominal typing. However, at a high level you can write the code in a very similar structural pattern as with what you get in c#/java.
- JaggerJo 4y agoI think you should give F# a shot instead. 1. No standard and easy way of implementing interfaces No problem in F#, you have interfaces, abstract classed, ... 2. Bad standard library In F# you have access to the full .NET standard library and ecosystem. There are also quite a lot of libraries that are especially designed to take advantage of F# (SQL libs for example). 3. Syntax problems 3.1 OCaml doesn’t have a single-line comment syntax. It's `//` for single line and `(* comment *)` for n line comments in F#. 3.2 It has for and while, but no break and continue. So you use exceptions with a try inside the loop for continue, and outside for break. Same in F#, use recursion. Generally F# solves some of the issues but definitely not all of them. Some are just in the nature of the Standard ML syntax I guess. 4. Rest of the package is also not that good - NuGet is a decent/good package manager. - Easy to install a complete dev env. - sane build system (MSBuild) - Great out of the box support in JetBrains Rider/ Visual Studio (for Mac/ Windows) or via a VS Code plugin (Ionide).
- ecshafer 4y agoF# is such a great language. The fact Microsoft seems to pretend it doesn't exist is bewildering. Surely the .Net ecosystem can have two languages being promoted.
- pjmlp 4y agoBefore F# came into VS 2010, we already had C#, VB, C++/CLI (nee Managed C++), IronPython, IronRuby, and all the third parties targeting the CLR. It is really not having a clue what purpose they want for F#, I bet they have repented to ship it on VS2010. First it was for libraries only, then during the VS Express days it was for Web development, now they are trying to pivot it into data analysis and ML, while DevDiv manages to bring Guido out of retirement and finally manages to pursuade CPython core team about improving its performance.
- AlotOfReading 4y agoF# was originally just kind of a passion project that MS insisted get productized to continue development. It's still very much an internal favorite within Microsoft Research and the Bing team, from my understanding.
- WastingMyTime89 4y agoThe last paragraph show this article for what is is. That's an Haskell fan trying to discredit Ocaml and doing it very poorly. It takes a special kind of writer to write an incorrect sentence about the expression syntax while quoting the actual definition from the specification which contradicts what's written just after. I generally disagree about the complaint regarding the syntax. If you indent the code properly and use parentheses as you should and the language invites you to do, none of this is ambiguous. That's bad code not bad language design.
- boxed 4y ago"the language invits you to do"? What does that mean? If it's the right thing to do it shouldn't be in invitation surely, but a syntax requirement?
- WastingMyTime89 4y ago> What does that mean? That's a best practice. Like always using braces in C or Java or not using ternary operators in hard to read way. The syntax is unambiguous but non obvious to read if you don't know precedence rules as it is for most languages. You can make it explicit using parentheses which you should. I personally agree that parentheses around tuples should be mandatory but it's fairly easy to just put them.
- boxed 4y agoThose are examples of C and Java being very bad. So yea, I think my point stands.
- WastingMyTime89 4y agoI’m not sure I understand your point then because the code in the article is definitely very bad OCaml which is what I have been trying to tell you from the start.
- 4y ago
- ubertaco 4y ago> Another example is the sequencing syntax <expr> ; <expr> and productions with <expr> as the right-most symbol: let test1 b = if b then print_string "1" else print_string "2"; print_string "3" > Here print_string "3" is not a part of the if expression, so this function always prints “3”. Well, yeah. Here's the equivalent Java code: void test1(bool b) { if (b) print_string("1"); else print_string("2"); print_string("3"); } You've chosen to use a single-statement "else" form _without_ "bracketing" it with `begin` and `end`: let test1 b = if b then print_string "1" else begin print_string "2"; print_string "3" end ...which is equivalent to this Java code, where you _also_ would have to "bracket" the else-block: void test1(bool b) { if (b) print_string("1"); else { print_string("2"); print_string("3"); } } You could argue that Java (and C, and C++, and Javascript, and...) has the same "ambiguous parsing problem", then -- except that it doesn't, and the author is just thrown off by `begin`/`end` as block delimiters instead of curly braces, which might be a sign that they've also never seen Ruby before, or Elixir, or Pascal, or....
- yodsanklai 4y agoIt's a non-issue IMHO. Just use parenthesis if you're unsure, then auto-format. You'll catch any issue that wan't caught by the typechecker by reading the diff.
- charlesetc 4y agoYeah auto format solves a lot of the syntax problems. Dangling else for instance is not at all ambiguous when you have automatic indentation.
- deleted 4y ago[deleted]
- yakubin 4y ago> You could argue that Java (and C, and C++, and Javascript, and...) has the same "ambiguous parsing problem", then -- except that it doesn't The author didn’t claim there’s any ambiguity in parsing, only ambiguity in reading as a human. And I would agree that all the languages you mentioned have the same problem. And this is a real problem as long as people use this form of if (which they do). New languages avoid this pitfall by mandating the use of braces, in return dropping the parens, and I think that’s great.
- cies 4y agoReasonML and ReScript are a (more or less the same) new syntax on top of OCaml. ReScript only targets JS, while ReasonML targets both JS and the native archs OCaml supports. Facebook and Bloomberg are using ReScript internally, afaik. Messenger.com is written in it. Facebook also maintains React bindings to ReScript. https://rescript-lang.org/ https://rescript-lang.org/ https://reasonml.github.io/ https://reasonml.github.io/
- giraffe_lady 4y agoRescript is completely excellent imo. I have used ocaml for years and while I like it more than most languages it's also weird and frustrating sometimes. Rescript uses the best parts of ocaml (type system & exhaustive pattern match, first class modules) to patch over the worst parts of js. It's almost alarming how effective it is to combine these two gnarly hostile languages like this. I also work in typescript a lot and it's the obvious comparison/competitor there. While it has objectively "won" it's so so much worse than rescript. Its type system is much more complex, untrustworthy inference, and ultimately is still unsound lol. Ocaml's type system is truly a wonder. Extremely practically helpful, complex enough to express anything without becoming a full blown language in its own right like eg typescript and haskell. Rescript compiles to very reasonable js and writing bindings is not particularly exhausting once you get the hang of it. I've been using it for a number of projects including completely irresponsible cases like deno fresh and it's been wonderful. What typescript could and should have been.
- frou_dh 4y agoHow does that work with Fresh? Just not using its built-in "Islands" machinery at all? Or smuggling stuff in that as far as Fresh is concerned are more orthodox React components?
- giraffe_lady 4y agoRescript has good react integration and compiles to normal js, so a little care to structure your rescript files so the compiled js ends up where fresh expects it is mostly all you need. The more worrying thing is that fresh uses preact while rescript explicitly uses react and so far doesn't have a way to change it. I just overrode react in the import map to link preact instead. This is frightening and fragile, since the interfaces aren't guaranteed to be identical. But it's been working fine on a personal project for a few months now.
- yodsanklai 4y ago1. To print values, nowadays you just derive pretty printers automatically. 2. Syntax? yes, it's not C-like... you'll get used to it in a few days. 3. Lack of interface? would be helpful to see a concrete example of what the author finds limiting. You have modules, functors, includes, objects, first-order modules... Personally, I find that plain modules are simple and go a long way. It's not perfect, but I find that nowadays Core/Dune/Opam/Merlin gives you a very decent developer experience.
- the_af 4y ago> 2. Syntax? yes, it's not C-like... you'll get used to it in a few days Since the author mentions Haskell as a positive example multiple times, I don't think a lack of C-like syntax is the problem for them here. Also, the author claims: > Since 2013 I’ve had the chance to use OCaml a few times in different jobs, and I got frustrated and disappointed every time I had to use it. So it's safe to assume "in a few days" their dislike for OCaml syntax won't go away. For the record, I don't think syntax is a big issue.
- yodsanklai 4y agoIncidentally, I find Haskell syntax more confusing, specifically the semantic indentation. But maybe I'm like the author, I don't use Haskell regularly enough so that the syntax sinks in.
- mattgreenrocks 4y agoBeen using Haskell full-time for a year or so now, and using it part-time a few years ago for a side project. The reliance on indentation is nice and light but definitely bites you every now and then.
- klester79 4y ago[dead]
- spqr233 4y agoI don't the author really gave Ocaml a chance. He argues that every language needs to have interfaces. I agree somewhat with that statement, but I think the truer statement is to say that every language needs to have some way of defining composition at a structural level. An interface allows you to pass different "structures" to the same function so long as they adhere to the same spec. In Ocaml this is accomplished through modules, functors, and module signatures. Ocaml's module signature can play the same exact role as interfaces in Haskell, Rust or F#. The module system is arguably more expressive than what can be accomplished to interfaces. To give an example, Ocaml suffers from the same problem as rust does with having two standard implementations of a async runtime. Just like rusts: tokio and async-std, ocaml has Lwt, Async, (and newly added to the mix Eio). Whereas in rust most libraries just implement one of these systems, and you'll have to use compiler directives to support both. Ocaml's module system means that you can describe the async runtime as a signature and make your entire library generic to the async runtime it runs on top of. Most of the well-used libraries do this, and so you don't have to worry too much about which runtime you decide to use. Clearly, a language that can do that must have in some place a system that can replace interfaces.
- boxed 4y agoTo me it seems he gave it a lot of chance in order to find this many problems. It does sound to me like you stopped reading after the first point. Maybe you didn't give the post a chance?
- spqr233 4y agoIt's more that only really strongly disagreed with that point. Frankly, there are some cons with using Ocaml. In practice, I think the library support for ocaml isn't completely there given the small community.
- WastingMyTime89 4y agoTo be honest, anyone who used Ocaml understands immediately that the author gave it no chance and went looking for problems. It’s obvious because the post lingers a lot about things which are not actually issues like type conversion but don’t talk about the very real issues Ocaml has (opam is not great, dune is weird).
- ywei3410 4y agoI don't think this list is fair at all. > No standard and easy way of implementing interfaces Firstly another commenter has mentioned [1] modules as interfaces. There is also the object system [2] which I've seen used to great effect in similar scenarios. Typeclasses and modular implicits are fantastic - being a heavy user of Scala and Rust; but I've always found that they tend to be best when used as an alternative to macros, for derivation purposes. The interface and code split in OCaml is also really nice for value types and comes with no limitations; for years, we had issues in Scala because of the host platform, and in Rust exposing functions for your newtype can be oddly boilerplate heavy. > Bad standard library The OCaml standard library is (infamously) anemic and obviously is not as fully-featured as something like Java or Python, but since alternative libraries tend to be compatible with the bundled StdLib (both use the same `option` and `list` type), it means that having libraries dependent on different ones is not a huge issue. Learning resources, can be confusing though. I'm not sure why it's a problem certain data structures are mutable and some are persistent; the documentation is usually fairly clear and you usually have a performance characteristic in mind when selecting your data structure. Universal equality and hashes are indeed a little annoying (here an `Eq` typeclass would be great!) but I do understand the original decision to have them inside. At the very least, it's not pointer based equality and since records and most types don't have subtypes, you don't run into as many issues. You can of course use the equality methods on the modules themselves and since `Hashtbl` and co have functors, you aren't penalized for it. Strings are a problem-ish (what older language doesn't have string issues ha!), but there is utf-8 support now with [3]. > but just two years ago it was common to use Makefiles to build OCaml projects It is true that OCaml has a unix-y flavour, but honestly I don't really understand the snipe at make. Sure there are alternatives, but make is bundled on most distros, has a quick startup time and a lot of people are familiar with it. More of the community is moving towards dune as well, which is pretty good; the docs could do with better indexing but there are some features such as promotion which are really nice. > was no standard way of doing compile-time metaprogramming I haven't used ppx much so I can't really comment here. Finally they've missed the biggest reasons to /use/ OCaml. [1] https://news.ycombinator.com/user?id=4ad https://news.ycombinator.com/user?id=4ad [2] https://ocaml.org/docs/objects https://ocaml.org/docs/objects [3] https://v2.ocaml.org/api/Stdlib.String.html#utf_8 https://v2.ocaml.org/api/Stdlib.String.html#utf_8
- Joker_vD 4y ago> It also has the “dangling else” problem: God I hate this term because it's not even a problem. For a human reader, it's pretty obvious that an "else" should belong to the closest "if"; and it's quite difficult to write a mechanical parser that would match "else" with the furthest "if" instead. So what is, exactly, the problem? That the grammar is technically ambiguous? Who cares? The authors of LR-generators? They don't, they have been resolving shift-reduce conflicts by default in favour of shifting for half a century already.
- iLoveOncall 4y ago[flagged]
- kajaktum 4y agoAny language that have exceptions are trash imo. It is clearly a relic of the old day. It works for CPUs but not people.
- Miltnoid 4y agoI used OCaml as my daily driver in grad school and my postdoc, and recommend my students use it. I think the main benefits of OCaml are: Functional Has mutable references Not lazy Haskell's type system is just better. But for large, complex systems that require performant code, it can be quite difficult to track the laziness, and sometimes life is just easier if I can use a mutable references. The author is completely correct that there's a big failure in the lack of a type-class-like system. This is why people ask so much for modular implicits. Core is also a decent standard library (though I don't know why they require sexp_of_t and t_of_sexp on like all their data structures). So I'd gladly use a different functional language with mutable references and strict evaluation. But there isn't any besides F#, and I have a Mac and don't personally want to figure out .NET on Mac.
- ywei3410 4y agoThey require `sexp_of_t` and `t_of_sexp` because of their workflow being based on them; such as expectation testing [1] and tools such as [2]. It's a less noisy alternative to json for many people. [1] https://blog.janestreet.com/testing-with-expectations/ https://blog.janestreet.com/testing-with-expectations/ [2] https://github.com/janestreet/sexp https://github.com/janestreet/sexp
- owenm 4y agoStarting with F# on Mac is worlds away from what it was in the past, I bet you could be up and running in 5 minutes: brew install dotnet-sdk dotnet new console -lang F# (in your project directory) Start VS Code in that directory, install ionide via extensions, write code… dotnet run
- JaggerJo 4y agoExactly. And you can even pick between 3 IDEs - JetBrains Rider (best IMHO) - Visual Studio for Mac - VS Code with Ionide
- devmunchies 4y agoSublime text too with the fsautocomplete LSP server.
- frou_dh 4y agoKnowing the virtually dead Standard ML is a curse when it comes to appreciating the aesthetics of OCaml. The two languages have similar syntax, but in just about every way they differ, OCaml syntax took the ugly road :(
- atbpaca 4y agoI learned OCaml two decades ago. It was great to learning algorithmics but I already had the feeling the language was old and awkward. Today there is Scala, Haskell, Rust, F# etc.
- deleted 4y ago[deleted]
- yawaramin 4y agoAll of which are, incidentally, either directly or indirectly inspired by OCaml or its ancestor ML :-)
- kthielen 4y agoThis piece focuses on complaints about ocaml, and the last half seems to just be syntax complaints (which I mostly ignore just because every language seems to have awkwardness in its syntax -- certainly Haskell, a language otherwise held up as an example, can be shown to accept some really weird text). Good things about ocaml that I think should be mentioned are Hindley-Milner type inference (some might argue this, but it's a very effective system for inferring types), and also straightforward semantics (it's usually pretty easy to look at some code and make a reasonably accurate guess about what it will do on real hardware -- compare with Haskell). I'm sympathetic toward the initial complaints here, which I also think are the most substantive. Type classes and qualified types, as in Haskell, would be very useful in ocaml/ML. The examples offered (show_of_int, show_of_double, ...) are valid, and also the related complaint that dishonestly broad types like structural equality (where runtime errors are raised for cases where the types are actually not supported) also make a compelling case for qualified types in ML. I made this project ~10 years ago after making similar observations: https://github.com/morganstanley/hobbes https://github.com/morganstanley/hobbes Things like structural equality and ordering are user functions here rather than magic internal definitions (e.g. equality is defined as a type class, and type class instances can deconstruct algebraic types at compile time to decide how to implement instances). But evaluation is eager by default, so it's pretty easy to reason about performance. And data structures can be persisted to files and/or shared transparently in memory with C/C++ programs without translation, also very convenient for the places where this was used. Actually we built some very big and complicated time series databases with it, used in both pre and post trade settings where ~15% of daily US equity trades happen. So I think these observations are useful and have passed through some pretty significant real tests.
- KingOfCoders 4y agoI found that one hilarious "The regex module uses global state: string_match runs a regex and sets some global state. "
- debugnik 4y agoThe builtin `str` regex library is obsolete anyway, most people use `re`[1], or sometimes bindings for pcre or Google's re2. [1]: https://ocaml.org/p/re/latest https://ocaml.org/p/re/latest
- crop_rotation 4y agoThe biggest problem I have with Ocaml is not the language, but the tooling and the libraries. The library ecosystem is not even remotely comparable to go or even rust. Jane street core is mentioned as a good option, but that library is the most popular undocumented library I have ever seen. There is not even some normal default structure every library follows (e.g go io.Reader). Compare this to languages with supposedly "worse" type systems like Java, which has a library for everything and high quality well documented libraries like guava and apache commons. I find it fine to use ocaml for a random weekend whim project, but wouldn't touch it with a 10 feet pole for professional work.
- oslac 4y agoIt is for these (tooling / library) reasons it is almost impossible to recommend it for any project, almost like Nix in that regard for me.
- illiarian 4y ago> like Java, which has a library for everything and high quality well documented libraries Unless it's a library that has been around for a while and is probably hosted at Apache. There was a marked shift in 2010s in expectations, and now we expect libraries and code to be somewhat well-documented. For older libraries... well, it's often "here's a dump of autogenerated reference files with maybe a blob of prefacing text at the top. Good luck."
- deleted 4y ago[deleted]
- mjdowney 4y agoRelated: https://twitter.com/zetalyrae/status/1639474931086901248 https://twitter.com/zetalyrae/status/1639474931086901248 My OCaml: let foo (x: bar): baz = (\* Is this quuxable? *) match is_quuxable x with | Yes -> (* Then, we have to ... \*) All the OCaml I see in the wild: qlet%bind f = 's 't 'a 'b (fun ꙮ -> ꙮ ((<_<')) ꙮ) [@@ppx_gov_backdoor (~b~e~p~i~s)]
- lysecret 4y agoThanks! Whenever I see a generic type i cry a bit.
- jimsimmons 4y agoFunctional programming community likes this stuff. They go into the classical mathematicians’ trap of writing more and more general versions of something even though it’s not necessary.
- nequo 4y agoI think this is partly because of the syntax. When we write human languages (that use a Latin script), we use punctuation to delineate the beginning and end of terms. In a language like C or Rust, terms are surrounded by commas, parentheses, angle brackets, and so on. In OCaml and Haskell, many things that there is syntax for in C-style languages are done as ordinary function calls, which separate terms by only whitespace. It is easier to read this (Rust): let value = some_long_ass_function_name(some_quirky_parameter, another_one); another_function(value) than this (Haskell): let value = someLongAssFunctionName someQuirkyParameter anotherOne in anotherFunction value or this (OCaml): let value = some_long_ass_function_name some_quirky_parameter another_one in another_function value Individual terms in camel case are difficult to read if they consist of more than a couple words. Consecutive terms in snake case are difficult to read because underscores and whitespace look alike visually. Haskell and OCaml's idiomatic solution is to use extremely terse names for arguments, type variables, and local variables, out of what seems to be syntactic necessity.
- 4y ago
- reikonomusha 4y agoCoalton [1] is an OCaml-like dialect of ML: it's strictly evaluated, has imperative features, and doesn't force a purity-based development philosophy. However, Coalton has S-expression syntax and integrates into Common Lisp. It works, and is used "in production" by its developers, but it's still being developed into a 1.0 product. Coalton made a lot of design decisions to work away from issues that this post describes. - Coalton dispensed with ML's module system of structures, signatures, and functors. No doubt a beautiful concept, and sometimes satisfying to write, but almost always unsatisfying to use due to how explicit one tends to need to be. Like the author suggests, the "interface-style" of type classes or traits has always felt more intuitive, despite losing the ability to have multiple implementations of an interface for a single type. (However, I've come to appreciate that different interfaces should require different types—as opposed to one type having many interfaces.) Coalton uses type classes. - Coalton has S-expression syntax. No indent rules. No precedence rules. No expression delimiters. All of the "tradition" of ML syntax is dispensed with into something that is a lot easier to read and write for complex programs... yes, provided you use ParEdit or similar - It should be no surprise that with S-expressions, you get Lisp-style macros. Macros in Coalton are just Common Lisp macros. No separate pre-processors. No additional language semantics to deal with. Arbitrary compile-time computation and/or codegen, completely integrated. - Because it's built on Common Lisp, Coalton gets something few (if any?) other ML-derivatives get: Truly incremental and interactive development. You can re-compile types, functions, etc. and try them out immediately. There's no separate "interpreter mode"; just a Lisp REPL. Coalton's language features are still settling (e.g., records are being implemented) and the standard library [2] is still evolving. However, it's been used for "serious" applications, like implementing a compiler module for quantum programs [3]. [1] https://github.com/coalton-lang/coalton https://github.com/coalton-lang/coalton [2] https://coalton-lang.github.io/reference/ https://coalton-lang.github.io/reference/ [3] https://coalton-lang.github.io/20220906-quantum-compiler/ https://coalton-lang.github.io/20220906-quantum-compiler/
- wk_end 4y agoThis looks excellent! I have a soft-spot for the elegance of Lisp but can't live without a robust type system. A few questions I didn't see immediate answers to on the GH page (sorry if I missed something/could've found those answers if I digged a little deeper): 1. Beyond the typeclasses you mentioned, how powerful is the type system beyond standard HM stuff? Are there GADTs/existential types? Any other interesting features? 2. The lack of records sounds like it might be a deal-breaker for current use. Is that as bad as it sounds? Is it something that is expected to be addressed soon? Are there any other large omissions? 3. How does it integrate into the existing Common Lisp ecosystem, if at all? Is there any friction there? 4. On that note: in the REPL example it looks like you need to wrap your expressions with (coalton ...), which feels like it'd get frustrating. Is there any way around that? I guess even a reader macro would help...but still wouldn't be ideal. 5. Is Coalton backed by any kind of corporate funding? And (assuming you're involved in Coalton in a professional capacity) ...you guys hiring?
- amyjess 4y agoOCaml is one of those languages (like Raku and Nim) that I really want to learn and do something in at some point but usually end up not bothering because it's easy for me to just start up new personal projects in Python like I'm used to.
- yawaramin 3y agoAnd it's easier for people who know OCaml to set up new personal projects in OCaml like they're used to ;-)
- belmont_sup 4y agoBut you can always just try ocaml for the sake of it, for the fun of it!
- xigoi 4y agoMaybe try Nim next time you have something performance-sensitive, or OCaml when your problem can be elegantly expressed in a functional way.
- aaws11 4y agoAlmost all modern statically typed languages have closures, higher-order functions/methods, lazy streams, and combinators that run efficiently. Persistent/immutable data structures can be implemented even in C. Also, OCaml has no tracking of side-effects (like in Haskell), and the language and the standard library have lots of features and functions with mutation, such as the array update syntax, mutable record fields, Hashtbl, and the regex module. The only thing that makes OCaml more “functional” than e.g. Dart, Java, or Rust is that it supports tail calls. While having tail calls is important for functional programming, I would happily give up on tail calls if that means not having the problems listed above. When you mix imperative and functional styles tail calls become less important. For example, I don’t have to implement a stream map function in Dart with a tail call to map the rest of the stream, I can just use a while or for loop. In my opinion there is no reason to use OCaml in a new project in 2023.
- hencq 4y agoYou might want to make it clearer that this is a literal quote from the last paragraph of the article. Are you posting this because you agree/disagree?
- choeger 4y agoSimply put, OCaml is very principled. There is a good reason for pretty much every design decision. The only thing one could argue is the lack of type classes, i.e., overloading. (Calling it "interfaces" is somewhat wrong.)
- vrglvrglvrgl 4y ago[dead]
- manymanydots 4y ago> No standard and easy way of implementing interfaces. > In Haskell, this is done with typeclasses ... > In OCaml there’s no way to do this. I have to explicitly pass functions along with my values, maybe in a product type, or with a functor, or as an argument. Haskell is a mixed community / paradigm language too. I routinely program in "Braindead Haskell" (keep stuff simple and direct as much as possible). Funnily, in that programming style, using typeclasses for _all_ interface types is bad style. Instead, the Handle pattern [0] can be used. Which really is just shoveling functions in a product type. And imagine - it works worderfully. Everyone has to find their own style I guess. [0]: https://jaspervdj.be/posts/2018-03-08-handle-pattern.html https://jaspervdj.be/posts/2018-03-08-handle-pattern.html
- Jeff_Brown 4y ago> the Handle pattern I love this so much.
- mcguire 4y ago"Lack of widely used operations such as popcount for integer types, unicode character operations." popcount is widely used?
- jorkadeen 4y agoAn alternative to OCaml is Flix (https://flix.dev/ https://flix.dev/) which attempts to address some of the critiques in the post. For example: > Bad standard library A particular goal of Flix is to have a consistent standard library based on type classes. > Standard types are sometimes persistent, sometimes mutable. List, Map, and Set are persistent. Stack and Hashtbl are mutable. In Flix immutable types are named List, Set, Map, etc. and mutable collections are prefixed with Mut, e.g. MutSet, MutMap, etc. Mutable data types also carry a region. > Also, OCaml has no tracking of side-effects (like in Haskell) Flix has an effect system that tracks purity/impurity. (I am one of the developers of Flix)
- weatherlight 4y agoComplete Feature List algebraic data types pattern matching first-class functions extensible records parametric polymorphism type classes higher-kinded types light-weight polymorphic effects type aliases Hindley-Milner type inference CSP-style concurrency buffered & unbuffered channels first-class datalog constraints polymorphic datalog predicates constraints with lattice semantics stratified negation interoperability with Java unboxed primitives keyword-based syntax redundancy checks monadic let\* expressions expressions holes compilation to JVM bytecode full tail call elimination core standard library parallel compiler architecture human friendly errors interactive mode Visual Studio Code support Nice!
- pdimitar 4y agoI know some of those words.
- networked 4y agoI have been keeping an eye on Flix. Thanks to you and rest of the Flix team for working on a bold but practical language. I wish you success. I think Flix is one of the most promising languages in the ML family. (Do you consider it an ML?) I love that it has embedded Datalog. I know it is pre-1.0, but I would still like to ask about adoption. Are there notable third-party open source projects in Flix yet? By "third-party" I mean created outside of Aarhus University and the University of Waterloo.
- omoikane 4y ago> Int.abs can return a negative number. The documentation for abs[1] explains: "Warning. This may be negative if the argument is Int.min_int." I think that's just the nature of two's complement and not necessarily a fault of OCaml. C++ is also like that[2]. [1] https://v2.ocaml.org/api/Int.html https://v2.ocaml.org/api/Int.html [2] https://gcc.godbolt.org/z/34b3GbvvT https://gcc.godbolt.org/z/34b3GbvvT
- anderskaseorg 4y agoIn C and C++, abs(INT_MIN) is undefined behavior. (C17 §7.22.6.1: “The abs, labs, and llabs functions compute the absolute value of an integer j. If the result cannot be represented, the behavior is undefined.” Footnote: “The absolute value of the most negative number cannot be represented in two’s complement.”)
- yawaramin 4y agoHonestly the way OP just throws out a scary-sounding 'well this is an obvious bug that abs can return a negative number', without giving the context that it's for the minimum value of a machine int type, really says it all. He doesn't have an interest in evaluating it fairly, he's just doing a hit piece.
- b33j0r 4y agoEveryone I’ve met, including on the steering committee, has been funded by high-frequency trading. Heck, I almost took a job on a handshake in manhattan on this premise. But it just seems, even now, archaic for the task. As the author mentions, the community is small, the integrations are weak. You will be working on legacy systems if anyone pays you well. Same with certain parts of national defense, but we’ll make fun of PDP-11’s and FORTRAN another day. Proactive thought: why don’t we fund a B-team to say, try using Julia? Even ERLANG has some superior qualities for these real-time audited tasks. (And hey, if you want employees for some reason, just use python).
- pauldirac137 4y agoThe author says: "If you have a reason to think that OCaml is the best choice for a new project please let me know your use case, I’m genuinely curious." I think it's overwhelmingly the best language for writing an interpreter or a compiler. I'm sure Haskell is also a good language for writing compilers, but whenever I tried writing interpreters in Haskell, I found myself fighting the laziness. Most of the criticisms listed strike me as things that bother people starting out in the language (syntax etc.) but which quickly become non-issues with more experience. And my experience with opam/dune has been _much_ more pleasant than with Cabal in Haskell (though ghcup has certainly improved matters). I think the infrastructure in OCaml, which admittedly used to be quite poor, is now on par with any other language, if not better. However, if your application domain is one in which few OCaml libraries exist (e.g. web programming) you probably should look elsewhere.
- toastal 3y agoI just wish the source code supported Unicode and the formatters supported tabs dispute the compiler accepting it.