[HN Gopher] My thoughts on OCaml
       ___________________________________________________________________
        
       My thoughts on OCaml
        
       Author : ghuntley
       Score  : 150 points
       Date   : 2023-04-25 12:44 UTC (10 hours ago)
        
 (HTM) web link (osa1.net)
 (TXT) w3m dump (osa1.net)
        
       | Miltnoid wrote:
       | I 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.
        
         | yawaramin wrote:
         | I think looking at it as a 'failure' or 'deficiency' is the
         | wrong mindset. OCaml makes a different tradeoff than Haskell.
         | In exchange for not having ad-hoc polymorphism, OCaml's functor
         | system allows much quicker compilation and easier-to-understand
         | type errors. Like everything in tech, it's a tradeoff.
        
         | ywei3410 wrote:
         | They 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/ [2]
         | https://github.com/janestreet/sexp
        
         | owenm wrote:
         | Starting 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 wrote:
           | Exactly. And you can even pick between 3 IDEs
           | 
           | - JetBrains Rider (best IMHO)
           | 
           | - Visual Studio for Mac
           | 
           | - VS Code with Ionide
        
             | devmunchies wrote:
             | Sublime text too with the fsautocomplete LSP server.
        
       | frou_dh wrote:
       | Knowing 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 :(
        
       | choeger wrote:
       | Simply 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.)
        
       | jorkadeen wrote:
       | An alternative to OCaml is Flix (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 wrote:
         | Complete 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!
        
         | networked wrote:
         | I 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.
        
           | jorkadeen wrote:
           | Thanks for the kind words.
           | 
           | Yes, I would definitely consider it a language in the ML-
           | family. Its core is based on Hindley-Milner (like StandardML,
           | OCaml, and Haskell) which I think is the hallmark of ML-
           | family languages. Flix sits neatly between Ocaml and Haskell
           | in that it allows side-effects (like Ocaml, unlike Haskell)
           | but they are tracked by the effect system. Hence one can
           | program in the spectrum between those two languages, but get
           | strong guarantees from the compiler.
           | 
           | In terms of adoption, we see a lot of people trying it out,
           | and there are some packages out there already, but nothing
           | too big yet. We recently added support for package
           | management, so hopefully that will help the community grow.
        
             | networked wrote:
             | Nice to hear about the package management.
             | 
             | Sorry, I wasn't clear. I meant to ask whether you
             | considered Flix "an ML" as opposed to just being in the ML
             | family. It's an ontological question, and not important, so
             | don't sweat the answer. I am just curious how Flix
             | developers see their project.
        
       | ywei3410 wrote:
       | I 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 [2]
       | https://ocaml.org/docs/objects [3]
       | https://v2.ocaml.org/api/Stdlib.String.html#utf_8
        
         | boxed wrote:
         | > Finally they've missed the biggest reasons to /use/ OCaml.
         | 
         | You missed writing what they are :P
        
       | xvilka wrote:
       | Building, LSP server, and immutability are definitely better in
       | 2023 than author describe in their article.
        
         | nequo wrote:
         | In what sense is immutability better? What changed?
        
       | kthielen wrote:
       | This 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
       | 
       | 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.
        
       | Joker_vD wrote:
       | > 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.
        
       | manymanydots wrote:
       | > 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
        
         | Jeff_Brown wrote:
         | > the Handle pattern
         | 
         | I love this so much.
        
       | KingOfCoders wrote:
       | I found that one hilarious
       | 
       | "The regex module uses global state: string_match runs a regex
       | and sets some global state. "
        
         | debugnik wrote:
         | The 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
        
       | ronnier wrote:
       | Why 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.
        
         | kaba0 wrote:
         | It 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.
        
         | jlouis wrote:
         | A 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 wrote:
           | The 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?
        
         | the_af wrote:
         | > _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.
        
         | decafninja wrote:
         | I'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.
        
           | tikhonj wrote:
           | I worked on a team using Haskell at Target for a few years
           | and we had a _massively_ easier time hiring compared to the
           | other data science /ML teams. I figure it came down to two
           | things:
           | 
           | 1. People are actively interested in using Haskell and
           | working with others interested in Haskell/PL/FP/etc. More
           | people want to do Haskell than there are Haskell jobs and
           | Haskell openings get massive word-of-mouth advertising.
           | 
           | 2. It's a way to show that we're willing to do something
           | different and interesting. Everybody _says_ they are, but how
           | do you actually demonstrate it? I remember one of the first
           | great hires we had was an OR professor who didn 't even know
           | about Haskell--but joined in part because what we were doing
           | was different and innovative.
           | 
           | If I ever end up starting my own company, I'm going to use
           | Haskell because it's so much _easier_ to hire for it--
           | completely opposite to the superficial  "common knowledge"
           | that guides executive decisions at large companies.
        
           | felixyz wrote:
           | Jane 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 wrote:
             | There'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 wrote:
               | So 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.
        
               | decafninja wrote:
               | "Bribed" is a crude way to describe it, but in a manner
               | of speaking, yes?
               | 
               | I think you might be a tad idealistic, and you might
               | think I'm being a tad cynical. Maybe the truth is in the
               | middle somewhere.
               | 
               | But throwing enough money at someone can talk. And not
               | throwing enough money at someone can also talk. Short of
               | being asked to do something unethical or illegal, what's
               | wrong with that?
               | 
               | Can you honestly say all of the talented top engineers
               | out there working for top paying companies are doing it
               | for the pursuit of technological perfection, and aren't
               | doing it at least partially for the good money?
               | 
               | I would say the same thing about doctors - people all
               | love to say you should not get into medicine for money,
               | but can we honestly say money isn't at least a factor in
               | whether someone decides to pursue a MD?
        
               | felixyz wrote:
               | > I think you might be a tad idealistic
               | 
               | Agreed :)
        
               | yawaramin wrote:
               | Ron Minsky of Jane Street has explicitly said, many
               | times, that their choice of OCaml _attracted_ great
               | developers who wanted to work with it.
        
         | lallysingh wrote:
         | .. 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 wrote:
           | Absolutely 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 wrote:
             | Very 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.
        
         | anthk wrote:
         | MirageOS and microkernels.
        
         | yafbum wrote:
         | Back 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 wrote:
         | > Why would a company use ocaml?
         | 
         | Why _wouldn 't_ a company use Brainfuck?
        
       | vrglvrglvrgl wrote:
       | [dead]
        
       | JaggerJo wrote:
       | I 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).
        
         | veec_cas_tant wrote:
         | Wanted to add my experience here: after writing C# code most of
         | my professional life, F# is a breath of fresh air. The type
         | system makes so many issues and annoyances I've lived with in
         | C# just disappear. Much like Rust, the compiler is capable of
         | providing so much more value when the type system is so
         | expressive. You can bang out a lot of code quite quickly and be
         | pretty darn sure it will work just because it compiles.
        
         | daxfohl wrote:
         | > NuGet is a decent/good package manager
         | 
         | I remember F# designed its own package manager (paket) because
         | of NuGet's deficiencies. I haven't been on that ecosystem for a
         | while now. Have things changed? (My memory is that paket added
         | friction and I eventually dropped it for nuget on my personal
         | projects).
        
         | ecshafer wrote:
         | F# 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 wrote:
           | Before 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 wrote:
             | F# 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.
        
               | pjmlp wrote:
               | Nowadays most of those folks are no longer at MSR, Don
               | Syme has moved into Github and I doubt they are into F#.
        
               | JaggerJo wrote:
               | Don is still working on F#. The F# team at MS now is
               | bigger than is was years ago. People from different
               | companies and the community are collaborating on compiler
               | and language features.
               | 
               | F# is beyond microsoft, a lot of early adopters are still
               | there.
        
               | pjmlp wrote:
               | Stand corrected on that one.
               | 
               | What are the fruits of that increased team on the VS,
               | VS4Mac and VSCode tooling, and .NET SDKs?
        
           | pyjarrett wrote:
           | > F# is such a great language.
           | 
           | I very much feel this, I found it productive, but it feels
           | like a complete ghost town. I'm considering swapping to Go
           | over using .NET for tooling/scripting.
        
             | JaggerJo wrote:
             | Really? Were you active in the slack/discord channels?
        
               | pyjarrett wrote:
               | I was poking around https://forums.fsharp.org/ and
               | https://www.reddit.com/r/fsharp/
        
         | hpstewed wrote:
         | I use F# at work. Really love the language but the connection
         | to the dotnet ecosystem is a curse as much as a blessing.
         | Having to operate in a world of nulls and exceptions can
         | reduce/nullify the amazing benefits of discriminated unions.
         | Often you are back to relying on the due dilligence of other
         | developers as a result.
         | 
         | I use a lot of rust in my spare time. The runtime guarantees it
         | offers make other languages feel like a house of cards in
         | comparison, including F#. I coincidentally picked up an ocaml
         | book yesterday seeking a more 'robust' alternative to F#.
         | Unfortunately it seems as though ocaml is even more niche than
         | F# (I doubt I'll be working for jane street any time soon)
        
           | WorldMaker wrote:
           | The C# compiler got a ton of new smarts around reference type
           | nullability and almost all of the BCL (.NET standard library)
           | got annotated for it. I don't know when F# will finally pick
           | up all the new compile-time smarts for Nullable Reference
           | Types, but it has been proposed and prototyped, at least [1].
           | 
           | [1] https://github.com/fsharp/fslang-
           | design/blob/main/RFCs/FS-10...
        
           | ragnese wrote:
           | > Having to operate in a world of nulls and exceptions can
           | reduce/nullify the amazing benefits of discriminated unions.
           | 
           | I've been saying this about Kotlin on the JVM for ages. Using
           | a Java dependency is an absolute last resort for me for those
           | same reasons you mention about .NET from F#.
        
         | HdS84 wrote:
         | I really wish to like F# but the line noise kills me every
         | time. I would kill for a "visual basic" f# where the absurd
         | terseness is replaced with a little less noise. E.g. instead of
         | seq use sequence, instead of abstract one letter symbols use
         | words.
        
           | JackMorgan wrote:
           | Perhaps you mean mix a little more noise into the dense
           | signal? There's very little noise in F#, it's almost entirely
           | dense signal.
           | 
           | One good thing is the ability to bind new operators, so if
           | you don't care to learn to read <> you could make it
           | something else. Or you could have a local binding for
           | Sequence so you don't have to use just Seq.
           | 
           | It's also possible to avoid almost all operators if you don't
           | like them. There's nothing wrong with using a limited pool as
           | long as you can get done the job!
           | 
           | I also prefer to name variables, functions, and parameters
           | with nice clear names, and I've not found F# to get in the
           | way of that.
        
           | JaggerJo wrote:
           | what noise?
           | 
           | I get your example of 'seq { 1; 2; 3; }' but list, array are
           | not even shortened.
        
             | HdS84 wrote:
             | Sorry, I literally forgot them. A lookup here refreshed my
             | memory: https://learn.microsoft.com/en-
             | us/dotnet/fsharp/language-ref...
        
           | vips7L wrote:
           | This is my exact issue with many "modern" languages. The code
           | is not meant to be read later.
        
       | amyjess wrote:
       | OCaml 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.
        
       | spqr233 wrote:
       | I 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 wrote:
         | To 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?
        
           | WastingMyTime89 wrote:
           | To 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).
        
             | hardwaregeek wrote:
             | Why are these things not issues? I think it's totally valid
             | for someone who doesn't understand OCaml to raise issues of
             | usability or documentation. It's not just the issues of
             | experts that are a concern. And it's very demoralizing to
             | get a "you're holding it wrong" response to a complaint.
        
               | WastingMyTime89 wrote:
               | Because they are not issues on a day to day basis when
               | you use the language.
               | 
               | I used Ocaml for a paid internship some years ago. I was
               | very much a beginner. Do you know how many time I felt at
               | loss or annoyed by type conversion or the precedence
               | rules for various part of the syntax? I never did.
               | 
               | The truth is you never encounter the precedence rules
               | when writing Ocaml normally using parentheses like a
               | normal human being and you don't convert that much
               | between exotic types. Most of the conversion you actually
               | do are between the same types and most of the time you
               | have to write converter anyway because there is logic
               | involved. I worked professionally as a Java developer for
               | a bit. I think I had to write more conversion code
               | between weird classes then than I ever did in Ocaml.
               | 
               | The issue is not telling people they are "holding it
               | wrong". The issue is that this is not what's going to
               | annoy you as an Ocaml beginner.
               | 
               | The author of this article is not even an Ocaml beginner
               | by the way. That's actually someone who used to work on
               | the Haskell compiler.
        
               | illiarian wrote:
               | > Because they are not issues on a day to day basis when
               | you use the language.
               | 
               | They still are. You just _internalize_ them. Progammers
               | are the world 's greatest masochists with the world's
               | biggest Stockholm syndromes, and we don't like to admit
               | it.
               | 
               | For example, his pain points about syntax ambiguity are
               | absolutely valid, and true. However, when you "use the
               | language every day" you learn to avoid those constructs
               | and extract them into separate functions for example
               | because "that's how it's always done, and it's a nice
               | little quirk of the language".
        
               | WastingMyTime89 wrote:
               | No, the syntax parts he criticises are not this kind
               | (they are not ambiguous by the way). What's in the
               | article is very unidiomatic OCaml incorrectly intended
               | purposefully to make it look like it's doing something
               | else than what it does.
               | 
               | You don't write tuples without parentheses because it's
               | weird, harder to read and no one does it. Same for the
               | precedence rules of expression. You just use _begin_ and
               | _end_ for blocks like you would use braces in C because
               | you actually want to write a block. No one is just
               | randomly writing nested code without them because well it
               | doesn't work.
               | 
               | It's not a quirk. The author is just complaining that you
               | have to mark blocks like in every language. That's a
               | weird thing to complain about.
               | 
               | I agree that the lack of as-hoc polymorphism is a
               | downside (I don't agree with how the article presents it
               | but the article is disingenuous from the start anyway).
               | Everyone would like to have modular implicit.
        
               | illiarian wrote:
               | > unidiomatic OCaml
               | 
               | > You don't write tuples without parentheses
               | 
               | > Same for the precedence rules of expression. You just
               | use begin and end for blocks
               | 
               | This is exactly what I wrote, but in a Stockholm-
               | syndrome-y way.
               | 
               | > The author is just complaining that you have to mark
               | blocks like in every language.
               | 
               | He points out a real ambiguity in the syntax where the
               | parser literally parses the same-looking and same-
               | behaving statements completely differently.
               | 
               | Sure it's solved by "you just write begin-end" workaround
               | that you internalise. Or it could be solved at the syntax
               | level (like erlang and elixir)
        
               | WastingMyTime89 wrote:
               | > This is exactly what I wrote, but in a Stockholm-
               | syndrome-y way.
               | 
               | Do you complain about having to put braces around C
               | expressions to not get unexpected behaviour from the
               | compiler?
               | 
               | > He points out a real ambiguity in the syntax where the
               | parser literally parses the same-looking and same-
               | behaving statements completely differently.
               | 
               | No, he doesn't. If that what you got from the article,
               | you were bamboozled. He points out that match, try and
               | (;) have different precedence which is not ambiguous.
               | Writing _begin_ and _end_ is not a workaround. That's how
               | you mark blocks which is what he should have done
               | because, well, he wants a block.
               | 
               | Erlang has exactly the same issue if you write
               | unidiomatic code by the way.
               | 
               | That's unsurprising because "don't write code implicitly
               | relying on precedence behaviour" is taught to virtually
               | all beginners in most programming languages.
        
               | lmm wrote:
               | If you shouldn't write code that way then it should be a
               | compilation error (or at the very least a warning) to
               | write code that way.
        
               | ModernMech wrote:
               | > The issue is that this is not what's going to annoy you
               | as an Ocaml beginner.
               | 
               | Sure, but tbf, the post is about what annoys the author,
               | not what would annoy beginners. As you say, the author is
               | not a beginner, and so their problems wouldn't be
               | beginner problems.
        
               | WastingMyTime89 wrote:
               | That's not the point I was making. They are not expert
               | problems either. How often as an expert do you think you
               | encounter precedence issues you were not encountering as
               | a beginner?
        
             | boxed wrote:
             | It sounds like it's weird and annoying to convert a value
             | to a string. That's pretty damning. Did I misunderstand?
        
           | spqr233 wrote:
           | It'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.
        
         | maleldil wrote:
         | > 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
         | 
         | Is this the program describing the interface it expects, and
         | the compiler matching that with the implementations structure
         | (e.g. Go interfaces, Python Protocols), or is it something
         | someone declares and the libraries implement?
        
           | yawaramin wrote:
           | Mostly the former. The compiler infers the type of the
           | implementation and ensures it conforms to the interface. But,
           | you can _further_ restrict the interface 's type to hide
           | details from the outside world.
        
         | actionfromafar wrote:
         | > 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
         | 
         | So ... can you ELI5 to me how that is different from how you
         | can for instance compile a C program against different libc
         | implementations?
        
           | kajaktum wrote:
           | I mean...you can technically have a function that take void*
           | and return void* be the interface. But you wouldn't be able
           | to represent things like iterator and chain them together
           | without care. In C you would be tripping all over the slight
           | details like forgetting to check errno or something.
        
             | actionfromafar wrote:
             | So, it's like C++20 then?
        
         | hardwaregeek wrote:
         | Politely, I feel like this is the issue with OCaml as a
         | community. You gave a beautiful answer about programming
         | language design and composition. But how does it feel to write
         | the language? How can you print a user defined data type? From
         | reading around, it seems like your options are: explicitly pass
         | a print function for that specific type, use a third party
         | library for printing, or (my "favorite") don't. Or how does it
         | feel to write a function that takes a generic that can be
         | printed, checked for equality, and read? Or to convert one type
         | into another type?
         | 
         | And we're still talking about semantics here. How does it feel
         | to use the language server? How does it feel to read the code?
         | To build the language? Ultimately that's what users judge a
         | language on. Yes, Rust in some ways has a worse form of
         | abstraction. It is global, not fully generic and doesn't allow
         | for overloading. But it creates a user experience that is
         | nicer. It lets a user print something and compare two variables
         | and do type conversions without having to scratch their head,
         | read a forum post and import a library.
        
           | yodsanklai wrote:
           | > How can you print a user defined data type?
           | 
           | Pretty much the same way you'd do in Haskell or Rust: you add
           | a `[@@deriving show]` directive to your datatype.
        
           | ywei3410 wrote:
           | > You gave a beautiful answer about programming language
           | 
           | You do the same thing as in Rust, Scala or Haskell and derive
           | the printer [1]. Then at the callsite, if you know the type
           | then you do `T.show` to print it or `T.eq`. If you don't know
           | the type, then you pass it in at the top level as a module
           | and then do `T.show` or `T.eq`.
           | 
           | > Or to convert one type into another type?
           | 
           | If you want to convert a type, then you have a type that you
           | want to convert from such as foo and bar, then you do
           | `Foo.to_bar value`.
           | 
           | We can keep going, but you can get the point.
           | 
           | You _can't_ judge a language by doing what you want to do
           | with one language in another. If I judge Rust by writing
           | recursive data structures and complaining about performance
           | and verbosity that's not particularly fair correct? I can't
           | say that Dart is terrible for desktop because I can't use
           | chrome developer tools on its canvas output and ignore it's
           | hot-reloading server. I can't say Common Lisp code is
           | unreadable because I don't have type annotations and ignore
           | the REPL for introspection.
           | 
           | [1] https://github.com/ocaml-ppx/ppx_deriving
        
             | hardwaregeek wrote:
             | Okay...so you have to add a third party library to print?
             | Yes, recursive data structures are a pain in Rust (well,
             | recursive multi-owner data structures). But that's like
             | comparing changing your oil to opening your car door. We do
             | one of these a lot more. And bear in mind, I had to find
             | this answer by googling and reading a random forum post.
             | That's some pretty poor documentation.
             | 
             | And that's not talking about aesthetics. `T.show foo` or
             | `Foo.to_bar value` is a lot of syntactic overhead for a
             | rather common task.
             | 
             | And again, these are the lesser concerns to the other ones
             | I outlined. Reading the code, building the code, and
             | understanding the compiler errors are the big ones.
        
               | agumonkey wrote:
               | People have to realize that printing is the least of your
               | concern. Visible representation is not solving problem.
        
               | ywei3410 wrote:
               | Not really third-party; ocaml-ppx is something similar to
               | `javax` in the Java space? But it is optional and doesn't
               | come bundled with OCaml.
               | 
               | Recursive structures are only rare in Rust _because_ they
               | suck to write and have terrible performance
               | characteristics in the language. In languages like
               | Haskell, OCaml and Scala using tagless initial encodings
               | for eDSL's [2] are really, really common.
               | 
               | I don't write Rust like I write any semi-functional
               | language with function composition because, well, it's
               | _painful_ and not a good fit for the language.
               | 
               | > `T.show foo` or `Foo.to_bar value` is a lot of
               | syntactic overhead
               | 
               | The `T.()` opens a scope so OCaml code generally looks
               | like:
               | 
               | ``` let foo = T.(if equal zero x then show x else "not
               | here") ```
               | 
               | for,
               | 
               | ``` fn foo(t: T) -> String { if(t == T::ZERO) { t.show()
               | } else { "not here".into() } } ```
               | 
               | Even when talking about usage, each language community
               | for better or worse has a predefined workflow in mind.
               | Your questions and workflow are specific to a particular
               | language; you don't, for example, ask about the REPL, the
               | compile times, debugging macros, the cold-start of the
               | compiler, whether hot-reloading is a thing, the debugger,
               | how it interacts with perf, how to instrument an
               | application. Presumably because the language you use or
               | the programs that you make don't have those components as
               | part of their main workflow.
               | 
               | [1] https://github.com/ocaml-ppx [2]
               | https://peddie.github.io/encodings/encodings-text.html
        
               | hardwaregeek wrote:
               | A lot of these things that you mentioned are valid flaws
               | in Rust. I'm not going to dismiss them as not important
               | or non-problems because they are genuine issues. Compile
               | times suck. We could use hot reloading and a REPL.
               | Debugging macros, instrumentation and perf stuff is good,
               | but I assume it could be better. That's what I expect
               | from a language community. Not constant denial about the
               | state of usability. And it really does feel like many of
               | the smaller language communities fall into this hive-mind
               | where type signatures are valid documentation and who
               | needs to use an editor other than emacs?
        
               | yawaramin wrote:
               | If you are referring to OCaml, many people in the
               | community care a lot about writing good documentation so
               | that it's not just the type signatures. In fact the OCaml
               | website team have made amazing leaps and strides
               | integrating package documentation directly in the
               | website.
               | 
               | And the experience using OCaml LSP Server with VSCode
               | nowadays is honestly pretty good--type annotations
               | displayed, error messages, go to definition, generating
               | interface files. The core functionality is all there.
        
               | hardwaregeek wrote:
               | That's good to hear! I don't mean to be too negative. I'm
               | genuinely glad that OCaml is making these strides. I'm
               | hopeful that OCaml can find its equivalent of Esteban
               | Kuber[1] and they can make the language a truly fun and
               | friendly experience.
               | 
               | [1]: https://www.youtube.com/watch?v=Z6X7Ada0ugE
        
               | yawaramin wrote:
               | You don't _need_ a third-party library to derive a
               | pretty-printer for your types, it just makes it simpler.
               | OCaml takes the approach that the core compiler doesn 't
               | do any codegen, that is left to PPXs (basically,
               | middlewares which transform code) which run before the
               | compiler.
               | 
               | You can write a pretty-printer yourself using the
               | conventions of the `Format` module. Is it manual and
               | annoying? Yeah. That's why the PPX exists. It's a
               | tradeoff.
        
               | yodsanklai wrote:
               | > `T.show foo` or `Foo.to_bar value` is a lot of
               | syntactic overhead for a rather common task.
               | 
               | A lot of syntactic overhead sounds like a stretch. I
               | suppose you could drop the `T` like you do in Haskell but
               | I personally like my language to be a bit more explicit.
               | It improves readability.
        
             | pdhborges wrote:
             | Scala is probably not a good example because if you need
             | some quick and dirty printing you can override toString and
             | keep the rest of the generic code intact. In OCaml, Rust
             | and Haskell you would have to add type constraints in a
             | bunch of places to make println! T.to_string and show work.
        
         | v0idzer0 wrote:
         | Came here to make this exact point. But I totally agree with
         | all of his other complaints. It's a good list of the cons, but
         | ignored the many pros
        
       | [deleted]
        
       | WastingMyTime89 wrote:
       | The 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 wrote:
         | "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 wrote:
           | > 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 wrote:
             | Those are examples of C and Java being _very bad_. So yea,
             | I think my point stands.
        
               | WastingMyTime89 wrote:
               | I'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.
        
           | Verdex wrote:
           | I agree, but the languages that actually do this are in a
           | hyper-minority, I feel. Nearly every language allows you to
           | do the wrong thing and then only lets you discover this at
           | runtime via exception OR sometimes even just by careful
           | examination of subtly incorrect output.
           | 
           | As such, this doesn't really feel like the best argument
           | against ocaml (and I believe arguments against ocaml do exist
           | and on a much more accessible level).
        
       | omoikane wrote:
       | > 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
       | 
       | [2] https://gcc.godbolt.org/z/34b3GbvvT
        
         | anderskaseorg wrote:
         | In C and C++, abs(INT_MIN) is undefined behavior. (C17
         | SS7.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.")
        
       | [deleted]
        
       | nu11ptr wrote:
       | I 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
        
         | lysecret wrote:
         | Same, big fan of f#.
        
         | JaggerJo wrote:
         | We use F# in prod. Could not be happier.
        
           | dimitrios1 wrote:
           | Completely 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 wrote:
             | Today 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#.
        
               | JaggerJo wrote:
               | + macOS
        
       | klester79 wrote:
       | [dead]
        
       | mjdowney wrote:
       | Related: 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)]
        
         | mcguire wrote:
         | Hmm. I haven't seen the latter in OCaml as much. More the
         | opposite; when I first used it, things like list length in the
         | standard library weren't tail recursive. 8-|
         | 
         | Now, Haskell and _shudder_ Scala _shudder,_ on the other hand.
        
           | WastingMyTime89 wrote:
           | Compared to Haskell, OCaml developers are generally not to
           | fond of custom operators which shield you from some of the
           | worst cases unless you are reading code an Haskeller wrote in
           | OCaml which happens.
           | 
           | For a long time, most of the users were either writing
           | compilers or static analysers for low level languages and a
           | fair share was very knowledgeable in C and system
           | programming. It had a huge impact on what was seen as
           | idiomatic. You can still find trace of it in for exemple the
           | system library which looks more like the C stdlib than a
           | modern standard library or how the compiler finds libraries.
           | 
           | Generally the community used to have a very different
           | "flavour" than the Haskell one (it was also very French to be
           | fair). I think I t's less true nowadays. Still I would fall
           | from my chair if I ever encounter someone working on the
           | OCaml compiler writing a disparaging disingenuous post on
           | Haskell. Meanwhile, we are here which reflects exactly my
           | general experience with the Haskell community.
           | 
           | Ppx are used more and more often however and it did make code
           | harder to read.
        
         | jimsimmons wrote:
         | Functional 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.
        
           | yawaramin wrote:
           | I don't think this is correlated to functional programming.
           | Programmers in general tend to over-architect because we're
           | often learning as we're going and sometimes it's more fun to
           | use some cool concepts. Since design patterns started
           | becoming en vogue back in the day, OOP codebases got filled
           | with those patterns. Now we are left picking up the pieces
           | with things like `AbstractProxyFactoryBean` or whatever. Same
           | thing with JavaScript where that ecosystem is infamous for
           | using tons and tons of npm packages to recreate simple
           | functionality, e.g. 'left-pad a string'. Arcane mathematics-
           | heavy FP code is just how that expresses in FP languages. And
           | in fact, OCaml is actually an antidote to that (for the most
           | part), because it deliberately offers a lower level of
           | abstraction than Haskell. I frequently say that OCaml is like
           | a cross between Haskell and Go.
        
           | nequo wrote:
           | I 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.
        
             | golergka wrote:
             | That's because of currying. If you want to partially apply
             | parameters, in your example, with Haskell we would just
             | have to do this:
             | someLongAssFunctionName someQuirkyParameter
             | 
             | And we get a function that accepts one parameter. But in
             | Rust you would have to do this:                       move
             | |another_one: i32| {
             | some_long_ass_function_name(some_quirky_parameter,
             | another_one)             }
             | 
             | Which is not easier to read.
        
               | nequo wrote:
               | It is true that currying looks comparatively awful in
               | Rust. But that is not because Rust uses parentheses and
               | commas. A hypothetical C-style language could use
               | dedicated syntax for currying, like
               | some_long_ass_function_name(some_quirky_parameter, ..)
               | 
               | which would be more readable without giving up on
               | punctuation.
        
               | ackfoobar wrote:
               | Scala does that, with `_` being a "hole in the
               | expression". I wouldn't call it currying though.
               | func(param1, _)
               | 
               | Every once in a while you have to make some change to
               | that expression.                 // you may want to write
               | func(param1, func2(_))       // but you need to write the
               | full lambda       param2 => func(param1, func2(param2))
        
             | oblio wrote:
             | Ah, now I realized, you're right. The lack of visual
             | distinction between different syntactic elements is what's
             | killing me.
        
         | actionfromafar wrote:
         | The latter code looks _totally_ quuxable.
        
           | gjm11 wrote:
           | Nah, I think it's already been quuxed up.
        
       | ubertaco wrote:
       | > 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....
        
         | yakubin wrote:
         | _> 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.
        
         | yodsanklai wrote:
         | It'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 wrote:
           | Yeah auto format solves a lot of the syntax problems.
           | Dangling else for instance is not at all ambiguous when you
           | have automatic indentation.
        
           | [deleted]
        
         | electroly wrote:
         | Agreed except for the part at the end: Java, C, C++, and
         | JavaScript definitely _do_ have the  "dangling else" problem!
         | It's a manifestation of the same basic issue. Who is saying
         | they don't? You just showed how they do! It is a real problem
         | and they all have it. The takeaway here isn't that those
         | languages _don 't_ have the issue. They do. It's just really
         | common in language design, that's all; certainly not something
         | to single out OCaml about. Apple's infamous "goto
         | vulnerability" was directly caused by this language design
         | issue in good old C.
         | 
         | https://en.wikipedia.org/wiki/Dangling_else (just to show that
         | this is something people commonly consider to be a problem with
         | Java, C, C++, and JavaScript)
        
           | ubertaco wrote:
           | >Java, C, C++, and JavaScript definitely do have the
           | "dangling else" problem! It's a manifestation of the same
           | basic issue. Who is saying they don't? You just showed how
           | they do! It is a real problem and they all have it.
           | 
           | Yeah, that's actually exactly my point: it's not some new
           | weird novel horrible broken parsing problem that only OCaml
           | has; rather, it's a common parsing rule that many languages
           | (including Java, C, C++, and JavaScript -- and yes, OCaml)
           | have.
        
         | Arnavion wrote:
         | Now keep reading on to literally the next sentence.
         | 
         | The article's point is that the `if-else` behavior is
         | inconsistent with `match`. And based on the part about double
         | quotes in comments, the parser seems to be fucked up something
         | fierce in other ways too.
        
       | atbpaca wrote:
       | I 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.
        
         | yawaramin wrote:
         | All of which are, incidentally, either directly or indirectly
         | inspired by OCaml or its ancestor ML :-)
        
         | [deleted]
        
       | s-zeng wrote:
       | A significant amount of these issues are solved by sticking to
       | Core, Dune, and avoiding imperative blocks
        
       | anthk wrote:
       | Ocaml5 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 wrote:
       | > No standard and easy way of implementing interfaces
       | 
       | Article -> trash.
       | 
       | Apparently the author doesn't know about OCaml modules, which is
       | _the_ defining feature of ML-derived languages.
        
         | koprulusector wrote:
         | Can you elaborate for us newer OCaml users? My first reaction
         | to this critique/point is the author must want mli, right?
        
           | [deleted]
        
         | sgeisenh wrote:
         | Especially if modular implicits land, you get the best of both
         | functions and typeclasses.
         | 
         | Pretty weird way to start the post.
        
           | wk_end wrote:
           | That'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 wrote:
         | Someone 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.
        
           | Verdex wrote:
           | To 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.
        
           | WastingMyTime89 wrote:
           | > I'm pretty sure is what the author meant.
           | 
           | Clearly not considering he mentions typeclass in the article.
           | 
           | Module signatures are similar to interface and parametrized
           | modules allow you to do what you would do with abstract
           | class: you define a signature and then write a module using
           | these functions. Parametrized modules are more or less a
           | generalization of functions which goes from module to module.
        
             | arc-in-space wrote:
             | Sorry, I initially wrote 'interfaces as in OOP' to
             | distinguish them from module interfaces, but had 'ad-hoc
             | polymorphism' in mind. 'interfaces' is much too overloaded
             | of a term.
        
               | WastingMyTime89 wrote:
               | Ocaml has no ad-hoc polymorphism but you can use
               | parametrised modules to write generic code which you will
               | have to specialise at some point. That brings you ninety
               | percents of the way in term of what ad-hoc polymorphism
               | is used for. It's more cumbersome but I prefer it to the
               | complexity involved by what Scala does for exemple.
        
               | ywei3410 wrote:
               | Would you not consider the object system to be ad-hoc
               | polymorphism?
        
               | octachron wrote:
               | The OCaml object system is still parametric polymorphism
               | (trying to pass itself as subtyping polymorphism through
               | row variables) rather than ad-hoc polymorphism: there are
               | still no functions that only work on a finite subset of
               | types. In other words, a function may work on any objects
               | that has a method `m`, but you cannot have the same
               | method that has different implementation for `int` and
               | `float`.
        
               | WastingMyTime89 wrote:
               | It uses structural typing not ad-hoc polymorphism. Plus
               | it's rarely used and it used to give hard to parse error
               | messages when you made type mistakes. I don't really see
               | it as an adequate replacement for ad-hoc polymorphism.
        
           | Errancer wrote:
           | The 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-
           | fo... but I have to note that I never worked in OCaml so this
           | is just my theoretical understanding.
        
         | sparkie wrote:
         | I can kind of understand the author's complaint. A problem with
         | OCaml is there are several different ways to achieve the same
         | thing, and they're not compatible.
         | 
         | For example, you can do OOP-like interfaces/abstract classes
         | with `class virtual`, but classes and modules don't mix
         | together nicely. Your virtual class cannot abstract over
         | modules, nor do functors abstract over classes.
         | 
         | So you end up either using modules/functors pervasively, or
         | using objects pervasively. It's like there's two separate
         | languages competing for use.
         | 
         | Using modules seems to be more common, but it overshadows some
         | features of OCaml's object system which are pretty unique to it
         | and useful: row polymorphism and functional objects.
         | 
         | Obviously, functors have a clear performance advantage because
         | they're expanded at compile time, and objects have the vtable
         | overhead.
         | 
         | I think it would be interesting to see a variant of OCaml which
         | goes all-in on the object side of things. Strip away the
         | modules and functors and a provide standard library based
         | around functional objects.
        
         | networked wrote:
         | The author brings up modules and functors. A more charitable
         | interpretation is that they want ad hoc polymorphism but are
         | handed parametric polymorphism instead.
        
         | Verdex wrote:
         | Yeah, I'm not sure I understand the author's complaint. OCaml
         | has modules, associated types, anonymous modules, GADTs,
         | polymorphic variants, and row polymorphism. All of which are
         | kind of like interfaces.
         | 
         | As far as I can tell, the complaint is maybe that ocaml doesn't
         | have something exactly like C#/Java interfaces (which I think
         | is a fair assessment). So maybe the author is lamenting that
         | they can't just rewrite their java code in every language?
         | 
         | Although, they also mention rust traits. Which at first blush
         | look _very_ similar to c# /java interfaces (at least closer
         | than anything ocaml has). However, at least in my experience,
         | rust traits don't quite fulfill the same niche as c#/java
         | interfaces because rust cares a lot about when you can figure
         | out the size of your objects. So every time I tried to use them
         | like I would a C# interface, I wound up regretting the
         | decision.
         | 
         | Ultimately, this article feels like a superficial "I don't like
         | ocaml" blurb. There is a lot to be warry of with respect to
         | ocaml. Although, the fact that ocaml still exists as a niche
         | language with a lot of very significant maintenance and active
         | development (effects + multithread recently landed), shows that
         | the author did not pay sufficient attention.
        
         | aseipp wrote:
         | The author is plenty aware of them, I can assure you (I used to
         | work with him on the Glasgow Haskell Compiler; most Haskell
         | programmers are plenty familiar with the ML module system, it's
         | a highly coveted feature by many.)
         | 
         | Anyway, what they're referring to has been rehashed a billion
         | times already in the relevant communities. ML functors being
         | good has little to do with it; even with functors and modules,
         | you're required to actually pass them around and construct them
         | explicitly and use it at call sites. If you want a Set for
         | Strings, you make an instance of the Set functor with the
         | proper implementation of the signature which specifies the Set
         | ordering (or whatever, assuming that's the signature needed),
         | but then you still have to _use_ the functor explicitly and
         | pass it around. You can have more than one, for good reason, so
         | making this explicit usage implicit is tricky. In contrast, in
         | Haskell, there is one ordering for each (nominal) type, so
         | there is no need to refer to specific instance of `Set String`
         | or whatever to define the ordering. `Set` uses `Ord`, which has
         | an unambiguous implementation. It is resolved implicitly for
         | you.
         | 
         | A lot of people just call this an "interface." Hell, even I do
         | that. It's just a generalized term for "ad hoc polymorphism"
         | where you don't need to guide instance resolution, I guess.
         | 
         | The author even quite literally (in like, the next sentence)
         | says that modular implicits would help this issue -- it would
         | allow many uses of an instantiated module to become more
         | implicit (e.g. uses of something like "turn this thing into a
         | string for debugging" without having a menagerie of individual
         | string_to_ functions). But they are not yet upstream. Even
         | then, implicits have their own tradeoffs, and the design
         | spectrum here has no clear winner. Even Haskell has adopted
         | Backpack, which takes a different spin on the whole thing using
         | mixin-modules (no functors), but tries to keep the
         | characteristic power of functors available in a languages where
         | typeclasses reign.
         | 
         | Much of this is also relevant in the design of theorem proving
         | communities, e.g. Lean4, which heavily relies on implicit
         | instance resolution in a similar form to modular implicits; yet
         | it doesn't have modules in the ML sense. They really want this
         | approach though, because in math you really do have lots of
         | instances you might refer to by name. But in programming it's
         | not always the same; implicit resolution of ad hoc instances is
         | often very useful.
         | 
         | It's not really a weird or unusual complaint, it's been
         | rehashed to death, but maybe it could be less ambiguous.
        
           | felixyz wrote:
           | Great comment. Thanks!
        
           | yawaramin wrote:
           | When writing about a language which has a well-known feature
           | called 'interfaces', it behooves the writer to not use
           | 'interfaces' to mean 'ad-hoc polymorphism' to avoid
           | confusion. Not doing so led to the predictable confusion.
        
       | cies wrote:
       | ReasonML 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://reasonml.github.io/
        
         | Taikonerd wrote:
         | Is ReasonML dead? Their last blog post is from August 2018...
         | https://reasonml.github.io/blog/
        
           | cies wrote:
           | Quieted down, but I depend on projects with worst graphs:
           | 
           | https://github.com/reasonml/reason/graphs/contributors
        
         | illiarian wrote:
         | The rescript-reason split killed both IMO. ReasonML was a very
         | tiny language to begin with. Splitting it into two split the
         | already tiny language and community into two minuscule ones.
         | 
         | And for no good reason (pun not intended).
         | 
         | And they were doing quite well, and influencing OCaml in good
         | and meaningful ways (like improving error reporting).
        
         | giraffe_lady wrote:
         | Rescript 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.
        
       | crop_rotation wrote:
       | The 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.
        
         | illiarian wrote:
         | > 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."
        
         | oslac wrote:
         | It is for these (tooling / library) reasons it is almost
         | impossible to recommend it for any project, almost like Nix in
         | that regard for me.
        
       | mcguire wrote:
       | " _Lack of widely used operations such as popcount for integer
       | types, unicode character operations._ "
       | 
       | popcount is widely used?
        
       | yodsanklai wrote:
       | 1. 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 wrote:
         | > _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 wrote:
           | Incidentally, 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 wrote:
             | Been 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.
        
       | reikonomusha wrote:
       | Coalton [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
       | 
       | [2] https://coalton-lang.github.io/reference/
       | 
       | [3] https://coalton-lang.github.io/20220906-quantum-compiler/
        
         | justinpombrio wrote:
         | > Coalton [1] is an OCaml-like dialect of ML: it's strictly
         | evaluated, has imperative features, and doesn't force a purity-
         | based development philosophy.
         | 
         | OCaml is also strictly evaluated, has imperative features (e.g.
         | ref), and doesn't force a purity-based development philosophy.
         | 
         | What makes you call Coalton a "dialect of ML"? ML's module
         | system is its defining feature, beyond that there's really not
         | much unique about it (by design). Would you call any language
         | with algebraic data types a "dialect of ML"?
         | 
         | EDIT: I'm picking on this one sentence, but the rest of your
         | comment is a good overview of the language, thanks.
        
           | reikonomusha wrote:
           | That's why I said it's "OCaml-like" followed by a colon: to
           | highlight the similarities.
           | 
           | As for why it's an ML dialect, maybe (maybe not) it's more
           | fair to call it "ML-inspired". Nonetheless, it's similar
           | enough to the ML family to be understood by ML programmers.
           | But yes, one of the major pillars of ML--the module system--
           | is conspicuously absent in favor of Haskell-like type
           | classes.
        
         | wk_end wrote:
         | This 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?
        
           | reikonomusha wrote:
           | 1. There are functional dependencies and multi-parameter type
           | classes. No GADTs (yet?) or existential types (yet?).
           | 
           | 2. Records are being implemented but it's far from being a
           | dealbreaker, in the sense that thousands of production lines
           | of Coalton have been built without needing them. It's just
           | not ergonomic to shuffle around and pattern match against
           | record-like data. With pattern matching in function
           | arguments, things are at least easier.
           | 
           | 3. All Coalton functions compile to Lisp functions. There's a
           | guide that describes what is promised about interop
           | (https://github.com/coalton-
           | lang/coalton/blob/main/docs/coalt...).
           | 
           | 4. Since Coalton functions are Lisp functions, you can call
           | (unconstrained) functions directly. However there's a lot of
           | room for improvement. There's an open issue to make a
           | dedicated Coalton REPL that can show types and not require
           | COALTON to be typed.
           | 
           | 5. Coalton is developed as an open source project to build
           | tools at HRL Laboratories, so it does receive sponsorship.
           | Yes, HRL is hiring. Feel free to send me an email to the
           | address in my profile.
           | 
           | As seems to be the case with any "serious" programming
           | language, there's always another thing to do--seemingly
           | perpetually--to make said language useful enough for
           | "serious" use. :)
        
         | networked wrote:
         | > Coalton has S-expression syntax. No indent rules. No
         | precedence rules. No expression delimiters.
         | 
         | This is a great selling point for a language in the ML family.
         | Programmers can't abuse infix operators when there are none.
         | :-)
         | 
         | Besides this, Coalton looks appealing. A highly interactive
         | statically typed language is something I have thought of. I am
         | sure I am not the only one. It is also a good sign that you are
         | using it as it is being developed.
        
       | aaws11 wrote:
       | Almost 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 wrote:
         | You 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?
        
       | kajaktum wrote:
       | Any language that have exceptions are trash imo. It is clearly a
       | relic of the old day. It works for CPUs but not people.
        
       | iLoveOncall wrote:
       | [flagged]
        
       ___________________________________________________________________
       (page generated 2023-04-25 23:00 UTC)