[HN Gopher] Multicore OCaml: April 2021
       ___________________________________________________________________
        
       Multicore OCaml: April 2021
        
       Author : sadiq
       Score  : 135 points
       Date   : 2021-05-13 10:23 UTC (12 hours ago)
        
 (HTM) web link (discuss.ocaml.org)
 (TXT) w3m dump (discuss.ocaml.org)
        
       | toolslive wrote:
       | What I'm still missing is a strategy to move existing ocaml
       | programs that use (let's say) Lwt for concurrency and a bit of C
       | for things that were trivial to parallelize to move to multicore
       | ocaml _AND_ benefit from it.
        
         | kcsrk wrote:
         | (One of the Multicore OCaml devs here)
         | 
         | We have prototyped offloading CPU intensive computations in Lwt
         | programs using Multicore OCaml [1]. We're currently working
         | with Lwt maintainers to upstream it.
         | 
         | [1] https://sudha247.github.io/2020/10/01/lwt-multicore/
        
           | anuragsoni wrote:
           | > We have prototyped offloading CPU intensive computations in
           | Lwt programs using Multicore OCaml
           | 
           | This is very interesting! I'm wondering if you are aware of
           | any discussions with the async maintainers about what their
           | plans are with the multicore runtime?
        
           | toolslive wrote:
           | thx! Another question. Suppose you're starting from scratch,
           | is it worth going the effects based async io route ?
           | https://github.com/kayceesrk/ocaml-aeio seems very
           | interesting...
        
       | dang wrote:
       | Past related threads:
       | 
       |  _Multicore OCaml: Feb 2021 with new preprint on Effect Handlers_
       | - https://news.ycombinator.com/item?id=26424785 - March 2021 (29
       | comments)
       | 
       |  _Multicore OCaml: October 2020_ -
       | https://news.ycombinator.com/item?id=25034538 - Nov 2020 (9
       | comments)
       | 
       |  _Multicore OCaml: September 2020_ -
       | https://news.ycombinator.com/item?id=24719124 - Oct 2020 (43
       | comments)
       | 
       |  _Parallel Programming in Multicore OCaml_ -
       | https://news.ycombinator.com/item?id=23740869 - July 2020 (15
       | comments)
       | 
       |  _Multicore OCaml: May 2020 update_ -
       | https://news.ycombinator.com/item?id=23380370 - June 2020 (17
       | comments)
       | 
       |  _Multicore OCaml: March 2020 update_ -
       | https://news.ycombinator.com/item?id=22727975 - March 2020 (37
       | comments)
       | 
       |  _Multicore OCaml: Feb 2020 update_ -
       | https://news.ycombinator.com/item?id=22443428 - Feb 2020 (80
       | comments)
       | 
       |  _State of Multicore OCaml [pdf]_ -
       | https://news.ycombinator.com/item?id=17416797 - June 2018 (103
       | comments)
       | 
       |  _OCaml-multicore now at 4.04.2_ -
       | https://news.ycombinator.com/item?id=16646181 - March 2018 (4
       | comments)
       | 
       |  _A deep dive into Multicore OCaml garbage collector_ -
       | https://news.ycombinator.com/item?id=14780159 - July 2017 (89
       | comments)
       | 
       |  _Lock-free programming for the masses_ -
       | https://news.ycombinator.com/item?id=11907584 - June 2016 (29
       | comments)
       | 
       |  _Lock-free programming for the masses_ -
       | https://news.ycombinator.com/item?id=11893911 - June 2016 (4
       | comments)
       | 
       |  _OCaml 4.03 will, "if all goes well", support multicore_ -
       | https://news.ycombinator.com/item?id=9582980 - May 2015 (113
       | comments)
       | 
       |  _Multicore OCaml_ - https://news.ycombinator.com/item?id=8003699
       | - July 2014 (1 comment)
        
       | philzook wrote:
       | It seems like great work.
       | 
       | Something I don't understand is that I hear people mentioning a
       | lack of multicore support as blocker to using a programming
       | language. I don't think this is something I have ever felt. What
       | problem domains require multicore?
        
         | sweeneyrod wrote:
         | Also, if no multicore blocks you from using OCaml, you also
         | have to stay away from Python/Ruby/JavaScript which also lack
         | it.
        
         | Buttons840 wrote:
         | When people buy a shiny new processor with 8 or more cores, I
         | think it's very natural to want to know you can utilize them.
        
           | slaymaker1907 wrote:
           | I think the question is more about what what use cases
           | require multithreading rather than just using multiple
           | processes.
        
             | sshine wrote:
             | In functional programming, simply mapping over data lends
             | itself to trivial parallelism. But yes, the use cases that
             | require it are much more interesting. Basically, background
             | processing.
        
         | blacktriangle wrote:
         | I feel the same way and I can't help but feel like I am missing
         | something. Concurrency is still inherently more complicated
         | than serial processing no matter what language features you
         | add, and it's amazing how far you can get just by scaling
         | across OS processes. I know there are plenty of domains that do
         | want multicore (ML, graphics), but it seems like even the
         | people writing line of business apps think lack of multicore is
         | a deal breaker for them.
        
           | gwmnxnp_516a wrote:
           | Forking new processes is less efficient than spawning new
           | threads as processes uses more machine resources and more
           | memory. In addition, communication between threads is far
           | more simple than communication between processes. Multicore
           | may not be deal-breaker for server applications, but it
           | matters for applications that require parallel processing.
        
             | gmfawcett wrote:
             | Forking a process on a modern Linux is relatively cheap
             | these days, and for many jobs you will just prefork all the
             | workers anyway. Passing messages via thread mailboxes or
             | IPC pipes are about equally complex endeavours.
             | 
             | If threads had never been invented, I suspect that 90% of
             | modern multicore programs would have done just fine on a
             | mixture of multi-processing and asynchronous I/O. (The
             | other 10% would have done poorly, though.)
        
           | hderms wrote:
           | Yeah I really don't know because OCaml already has async
           | constructs. It doesn't seem like it should be a dealbreaker
           | for most. That being said, it has a reputation for being
           | extremely performant so it might just be that people feel
           | like it's so close to being usable in a lot of situations it
           | currently isn't so there is more aggregate desire to allow
           | for multicore execution
        
           | toolslive wrote:
           | Often, it's just about finding a stick. They don't want to
           | use OCaml and the absence of multi-core features gives them
           | the excuse they were looking for. Now they can inform
           | management: "OCaml is not an option. we'll stick with <insert
           | PL here>"
        
             | sshine wrote:
             | It often is.
             | 
             | But sometimes it is also about finding more reasons to use
             | one of your favorite languages.
             | 
             | I'm doing pseudo-async PHP at work, and having proper
             | support would certainly make these solutions less brittle.
        
               | [deleted]
        
         | xfer wrote:
         | Anytime you need some parallelism like processing chunks of
         | data independently? Using processes to do it is not very
         | ergonomic.
        
           | gmfawcett wrote:
           | It depends? It's easy in Ocaml to fork child processes, set
           | up pipes, and pass messages back and forth. There are
           | libraries that paper over the details (or you can roll your
           | own, as I suspect many of us have done over the years).
           | 
           | That approach is not suitable for every workload, but fine
           | for most map/reduce applications.
        
       | sadiq wrote:
       | Happy to answer any questions.
        
         | NanoCoaster wrote:
         | I'm sorry if these are dumb questions, I'd be totally fine with
         | some pointers in the right directions if you don't want to
         | waste your time :)
         | 
         | I'm under the impression that the implementation is based on
         | algebraic effects. Does that include extending the language in
         | a way that lets users define their own effects & handlers?
         | 
         | Also, how's the performance? Last time I looked this stuff up
         | (and played around with Eff), which was quite a while ago, I
         | was told that regular usage of effects may impact performance
         | quite noticeably.
        
           | sadiq wrote:
           | Not dumb questions at all.
           | 
           | Multicore adds parallelism via Domains (which are essentially
           | heavyweight threads) and concurrency via Effects and fibers.
           | There's a multicore GC that supports both of those.
           | 
           | We plan to upstream things in two parts. First domains-only
           | parallelism and then effects as a follow-up. When the latter
           | lands users will be able to define their own effects and
           | handlers, yes.
           | 
           | Performance is pretty good, you can see our PLDI2021 paper
           | for a proper performance evaluation and loads more details:
           | https://arxiv.org/abs/2104.00250
        
             | NanoCoaster wrote:
             | Thank you, interesting stuff. Very much looking forward to
             | user-definable effects! I like Ocaml in principal, but
             | haven't yet strayed beyond learning the very basics some
             | time ago. Seeing a usable implementation of algebraic
             | effects in a somewhat popular language...that I gotta see
             | :)
        
               | sadiq wrote:
               | Worth pointing out you don't just need to stop at seeing
               | it, you can get started playing around with it today:
               | https://github.com/ocaml-multicore/multicore-
               | opam#install-mu...
        
               | NanoCoaster wrote:
               | Cool, thanks for the link. Will definitely play around
               | with it as soon as I find the time.
               | 
               | Too many programming languages, too little free time,
               | sadly.
        
         | mirekrusin wrote:
         | Is it currently possible to play with multicore ocaml on M1?
        
           | mseri wrote:
           | I think not yet: https://github.com/ocaml-multicore/ocaml-
           | multicore/issues/86...
           | 
           | Fwiw, OCaml itself can be compiled natively on M1.
        
             | sadiq wrote:
             | Yes, arm64 support is non-functional but we're planning to
             | get it back in to a working state very soon.
        
         | 4ad wrote:
         | Algebraic effects as described in the OCaml papers about
         | effects are dynamically typed. I recently heard in some talk
         | that this idea was abandoned, and the new algebraic effects are
         | in fact statically typed. Do I remember this correctly? If so,
         | where can I read about these new algebraic effects?
        
         | wuschel wrote:
         | Hello sadiq, I have some more general questions for you:
         | 
         | As understand that currently, the situation is analogous to
         | Python. The GIL allows for process based concurrency, with the
         | well known disadvantage regarding memory consumption. Also, my
         | guess is that OCaml relies library based solutions at the
         | moment?
         | 
         | 1) What does the introduction of MultiCore potential mean for
         | Ocaml? Will Ocaml be a much better fit to run a webserver
         | backend? Could you perhaps give a comparison to other
         | programming languages?
         | 
         | 2) How will Ocaml stand out with Multicore in the PL world, and
         | what solutions would be it uniquely suited for?
         | 
         | 3) What tools are going to be present to deal with bugs
         | introduced by your new runtime e.g. race conditions?
         | 
         | 4) If one wants to have a go at Multicore and play around with
         | it, where/how do I start?
         | 
         | Many thanks!
        
           | sadiq wrote:
           | Good questions!
           | 
           | 1) As I mentioned in
           | https://news.ycombinator.com/item?id=27142502 there is
           | support for parallelism and concurrency.
           | 
           | Giving an example of where these might be useful in a
           | webservice.
           | 
           | The addition of shared-memory parallelism is beneficial where
           | you might have a great deal of shared state that needs to be
           | used to service requests. An in-memory cache is a good
           | example - with a processed-based approach managing
           | read/writes and avoiding significant overhead from
           | marshalling the data is difficult.
           | 
           | Concurrency via effects at a minimum can make writing
           | network-based services much more pleasant (and debuggable!).
           | See the examples in https://arxiv.org/abs/2104.00250 where
           | programs can be written in a direct-style similar to blocking
           | IO but using effects are transformed to use asynchronous
           | interfaces. There's work going on in the project at the
           | moment to build fast cross-platform IO implementations that
           | sit atop of uring/gcd/iocp.
           | 
           | 3) This is a good question and one we're still working on. I
           | think one of the lead developers KC has a few good ideas
           | about instrumentation we can do to enable detecting races to
           | global state. It's certainly going to be an issue for people
           | porting large codebases.
           | 
           | 4) This is the place to start: https://github.com/ocaml-
           | multicore/multicore-opam#install-mu... .
        
         | agumonkey wrote:
         | How much resources are going into multicore compared to other
         | needs / improvements in ocaml (if any) ?
        
           | sadiq wrote:
           | Not sure I have enough of an overview to comment on that in
           | general, unfortunately.
           | 
           | The overview Anil gave at the end of last year on the OCaml
           | Platform should give you an idea of the many other strands of
           | work that are going on: https://ocaml.org/platform/
        
         | intc wrote:
         | Could you explain (in simple terms if possible) how the
         | Multicore OCaml achieves a memory model which is much simpler
         | on more efficient than in Java or C (mentioned at
         | https://github.com/ocaml-multicore/ocaml-multicore/wiki)?
         | 
         | Didn't see any mentions of critical sections (mutexes) with C++
         | examples in the documentation ("Bounding Data Races in Space
         | and Time"). I'm not sure I understand the comparisons the
         | writers are presenting.
        
           | jlouis wrote:
           | The key problem is program transformation, and in particular
           | optimizations. Different CPUs/ISAs, and compilers, might want
           | to transform your program to make it run faster.
           | 
           | However, in the multi-core setting, data races pose bounds
           | and limits on how much you can trigger those optimizations.
           | The program doesn't generally execute sequentially in a way
           | that can be entirely reasoned about. Instructions might be
           | reordered for the sake of the program to run faster.
           | 
           | Programmers can't work with that. So one proposes a memory
           | model. Follow these rules, and our optimizations won't alter
           | the behavior of the program. They kind-of describes what
           | happens "in between" the critical sections of the program,
           | hence the lack of a mutex mention.
           | 
           | The paper presents a local property and then shows, formally,
           | that this property is enough to guarantee an efficient memory
           | model. That is, a model in which you can perform
           | optimizations, while programmers can still reason about the
           | programs behavior.
           | 
           | The crux of the paper is that the property is local. This is
           | new, because memory models which came before it are global:
           | to reason about correctness, you have to consider the whole
           | program, rather than consider a small (local) subset. OCaml
           | requires more safety than most programming languages, so this
           | is good for the fact that you can now compose local fragments
           | of OCaml programs, without having to worry about a global
           | safety property.
           | 
           | The property is also simpler for programmers to reason about.
           | 
           | The way you "use" the paper is that you adapt your
           | optimizations to follow the property, and you make sure that
           | the virtual memory model is implemented the same way on
           | different architectures.
           | 
           | Finally, the examples: they explore the idea of a local
           | reasoning. In particular, they show why the (existing) global
           | properties fail if you view them under the stronger
           | requirement of local reasoning. It's the setup for the paper,
           | since it means you can't just use the existing models. They
           | need to be adapted if you want a more localized property.
        
           | kcsrk wrote:
           | (One of the authors of the mentioned paper [1])
           | 
           | Firstly, if you are using high-level synchronisation
           | mechanisms such as mutexes and condition variables, or
           | higher-level concurreny libraries such as
           | java.util.concurrent, you shouldn't worry about the memory
           | model. C++, Java and OCaml ensure that properly synchronised
           | programs do not exhibit surprising behaviours. Such programs
           | have sequentially consistent semantics i.e, the observed
           | behaviour is one of the permitted interleavings of the
           | threads in the program. Rust inherits C++ memory model [2],
           | but if you are using the safe subset, then you will never
           | have to think about it. Memory model is important only to
           | those who write the concurrency libraries. If you are still
           | keen, read on.
           | 
           | The OCaml memory model is certainly simpler than the C++ and
           | Java memory model, but being more efficient is not one of our
           | goals. C++ memory model permits a partially-ordered lattice
           | of stronger memory accesses starting from access to non-
           | atomic memory locations to sequentially consistent access
           | with increasing cost as you move up the lattice. OCaml memory
           | model only provides two -- atomic and non-atomic,
           | representing approximately the top and the bottom of the
           | lattice.
           | 
           | OCaml memory model is also stronger than Java in that our
           | data races are bound not-only in space like Java (data races
           | on certain variables don't affect behaviours on other
           | variables) but also in time (surprising behaviours stop
           | affecting the program after the race ends unlike Java; see
           | example 2 from [1]). This permits modular reasoning of racy
           | and non-racy parts of the program which is not the case with
           | C++ and Java.
           | 
           | The catch is that we have to disallow load-to-store
           | reordering to get the stronger guarantees. Relaxed memory
           | models such as ARM and Power do in fact permit these
           | reorderings, and we have to compile OCaml code (including
           | sequential one) such that the load-to-store reordering is
           | disallowed. This can be done fairly cheaply. It is free on
           | x86 which doesn't perform load-to-store reorderings, and has
           | a small cost (up to 3%) on ARM and Power architectures whose
           | memory models permit load-to-store reorderings.
           | 
           | [1] https://kcsrk.info/papers/pldi18-memory.pdf
           | 
           | [2] https://doc.rust-lang.org/nomicon/atomics.html
        
             | troutwine wrote:
             | > Rust inherits C++ memory model [2], but if you are using
             | the safe subset, then you will never have to think about
             | it.
             | 
             | Small correction, atomics are part of the safe subset of
             | Rust. At a certain point it's important to have a work-a-
             | day knowledge of the memory model with regard to atomic
             | numerics. Dealing with allocated types, now, that's a whole
             | different area and is specialized knowledge.
        
               | tialaramex wrote:
               | Still learning Rust here. If I use Rust's safe subset
               | Atomics, am I correct in thinking that I am able to write
               | code that on some platforms does something I didn't
               | expect because I didn't ask for an Ordering I needed to
               | make it do what I meant?
               | 
               | For example if I implement an algorithm that ought to be
               | Acquire / Release (e.g. to build my own custom mutual
               | exclusion) but I tell Rust it's OK to have Relaxed
               | semantics, it sounds like on this PC (an x86-64) it will
               | work anyway, but on some other systems it won't.
               | 
               | And I'd have achieved this goof without writing unsafe
               | Rust, just the same way as if I screwed up a directory
               | traversing algorithm because I relied on semantics not
               | present in all file systems?
        
               | troutwine wrote:
               | This is a good question. Yes, it's exactly the same kind
               | of problem. There is potentially a difference between
               | Rust's memory model and what's actually present on any
               | given target host. x64 has a "strong" memory model which
               | that ordering will always be implicitly acquire/release.
               | Compare this to ARM which is "weak" where your relaxed
               | ordering will actually be relaxed. (There's actually
               | quite a bit more nuance, discussed well here[0].) It's
               | important to write code that is correct with regard to
               | Rust's memory model so that it's portable, but if you
               | don't have a weakly ordered machine to test on it's
               | tricky. Loom[1] is helpful in this regard. This is true
               | of any language that allows you to write atomic code
               | where you specify the ordering.
               | 
               | [0] https://preshing.com/20120930/weak-vs-strong-memory-
               | models/ [1] https://github.com/tokio-rs/loom
        
               | zRedShift wrote:
               | You can play with atomics as much as you want in safe
               | Rust but you can't cause a data race without aliased
               | mutability, which means using UnsafeCell, raw pointer
               | operations or a & to &mut transmute (unsound and UB as
               | long as noalias is enabled in LLVM), and all require
               | unsafe.
        
         | hajile wrote:
         | StandardML implementations have had good multicore support for
         | decades now despite having only a tiny fraction of the users
         | and development time. Meanwhile, Ocaml has been promising
         | support for years.
         | 
         | What in Ocaml makes this so much harder to implement?
        
           | sadiq wrote:
           | As the sibling comment mentions, the hard part is actually
           | retrofitting multicore whilst maintaining compatibility _and_
           | performance.
           | 
           | Our paper last year covers most of why this is tricky:
           | https://arxiv.org/abs/2004.11663
        
           | rwmj wrote:
           | OCaml (or its immediate predecessor[1]) had a multicore
           | implementation, but it was dropped because of its complexity
           | and effect on single-thread performance. The challenge is to
           | add it back in a way that is maintainable and doesn't
           | negatively affect current users.
           | 
           | [1] https://www.researchgate.net/publication/2774662_Concurre
           | nt_...
        
       | terminalserver wrote:
       | For the lay person, what is the advantage of ocaml over other
       | languages?
       | 
       | Why would I reach for it?
        
         | systems wrote:
         | OCaml is everything D wanted to be, but failed
         | 
         | OCaml is high performance, Garbage Collected, hybrid system and
         | application programming language
         | 
         | You can use OCaml to write high performance Apps and System
         | tools without worrying too much about performance, or doing
         | crazy manual memory management
         | 
         | I would also say, if you like Go, but think you hit a wall with
         | it, then try OCaml
         | 
         | system programming language: C, C++, Rust
         | 
         | Hybrid system and application languages: OCaml, Go , D
         | 
         | If you need a language in this class (Hybrid system and app)I
         | think currently Go and OCaml are your only options, Go being
         | closer to C, Java familly of languages and OCaml is an ML
         | language, so choose as per your preference
        
           | vips7L wrote:
           | Why do you think D isn't an option?
        
             | systems wrote:
             | Well, D have a GC, and by design cannot have a GC with good
             | performance, because of its complex mutable object system
             | 
             | OCaml, can achieve good GC performance because its
             | immutable by default
             | 
             | D by design, will never outperform OCaml, at least this is
             | my understanding
             | 
             | That, and I think D's community is too small to fix the
             | language, while it does have several brilliant members and
             | developer, its just too small and underfunded
             | 
             | So, you have two reason why D should not be an option the
             | first technical ( D will never have a good GC ) the second
             | is more of a logistics issue, the community is just not
             | there to support a language as complex and as ambitious as
             | D and deliver on all its claims
        
               | vips7L wrote:
               | > Well, D have a GC, and by design cannot have a GC with
               | good performance, because of its complex mutable object
               | system. OCaml, can achieve good GC performance because
               | its immutable by default
               | 
               | I'm not so sure considering Java probably has better GC
               | performance than D/OCaml/Go and is completely mutable.
        
               | systems wrote:
               | what i know is that it is inherently harder to have good
               | GC performance with mutable language
               | 
               | and as i said D has a very small community Java is on the
               | opposite side of this spectrum its immensely popular, and
               | as I understand it took Java several iteration, and tons
               | of resources before gaining good performance, and still
               | today, Java optimization is a specialized experts job
        
               | pjmlp wrote:
               | D also suffers from the community always racing after the
               | next big thing without fixing the current set of issues.
        
               | vips7L wrote:
               | > Java optimization is a specialized experts job
               | 
               | No its not. Modern Java GC's require 0 tuning. ZGC with
               | default settings can achieve submillisecond pauses.
               | 
               | > and as i said D has a very small community Java is on
               | the opposite side of this spectrum its immensely popular,
               | and as I understand it took Java several iteration, and
               | tons of resources before gaining good performance
               | 
               | This wasn't your argument. You stated that _mutability_
               | was the reason that D couldn 't have a good GC, not the
               | size of its community or resources. According to tiobe D
               | is more popular than OCaml as well.
        
           | Serow225 wrote:
           | F# would probably sit in there somewhere too a little more on
           | the app than system side, although you don't see many uses of
           | the more low-level stuff that's been made available in the
           | later releases of .NET, it's there for use in F#
        
           | pjmlp wrote:
           | That language is C# not OCaml, specially with the
           | improvements done after version 7.
        
           | abhijat wrote:
           | Is Haskell a good fit for your hybrid category, similar to go
           | and ocaml, considering it also compiles to native?
           | 
           | I haven't heard of Haskell being used for the kind of "high
           | level" systems programming that go is used for.
        
             | willtim wrote:
             | In my opinion, as a professional haskell developer, it is
             | too hard to reason about the runtime space usage of Haskell
             | programs to ever recommend Haskell as a "systems
             | programming language". Haskell would be great for writing a
             | DSL for generating such code though.
        
         | lmm wrote:
         | I consider OCaml the baseline for what a language from the last
         | 20-or-so years should be. It doesn't do much that really pushes
         | boundaries, but it has all the basic things you want and no
         | major blunders (which is a surprisingly rare thing). In
         | particular it has a sensible type system with proper algebraic
         | types (which so many languages manage to get subtly wrong, even
         | today), full pattern matching, and very little in the way of
         | control flow keywords.
        
           | usrnm wrote:
           | > no major blunders
           | 
           | No multithreading seems to be a pretty big problem.
           | Hopefully, it will be fixed soon, but still
        
         | Blikkentrekker wrote:
         | Some of the rather impressive type system features of _Ocaml_ :
         | 
         | - Modules can be stored in variables, based on runtime
         | conditions, this is all statically type checked to ensure tht
         | the module exports the binding of the proper type. Modules can
         | also be passed to functions and functions can produce different
         | results based on which module is passed.
         | 
         | - There are keyword arguments and optional arguments with full
         | static type checking.
         | 
         | - It has full support for row type polymorphism, or "static
         | duck typing" as some call it: it tests statically whether an
         | object quacks like a duck.
         | 
         | https://dev.realworldocaml.org/first-class-modules.html
        
         | Steltek wrote:
         | Jane Street, financial trading company, uses OCaml a ton and
         | publishes a lot of their libraries.
         | 
         | I played with it some back when I was dabbling in every
         | language I could get my hands on. About when Scala was new (and
         | constantly breaking between releases) and before Rust, Go, JS
         | v8 were around. I really liked the functional aspect, which
         | wasn't bolted on after the fact, and that it could be compiled
         | to a real binary, not interpreted bytecode. In my naive youth,
         | I viewed AOT compilation as the path to a true high level
         | language that was also fast.
         | 
         | While it was neat, I moved on to Lisps/Schemes and now modern
         | JS is my very happy compromise of functional and practical.
        
         | Taikonerd wrote:
         | OCaml is...
         | 
         | * functional
         | 
         | * strongly, statically typed
         | 
         | * garbage-collected
         | 
         | OCaml can compile to a native binary, or to JS via ReScript
         | (formerly BuckleScript).
        
           | Zababa wrote:
           | > OCaml can compile to a native binary, or to JS via ReScript
           | (formerly BuckleScript).
           | 
           | It can also compile to JS via js_of_ocaml!
        
           | christophilus wrote:
           | Also, it compiles very quickly compared to most other
           | statically typed languages; especially compared to more
           | advanced ones.
        
         | yawaramin wrote:
         | That's difficult to answer without knowing what you want from a
         | programming language/stack.
        
         | richeyryan wrote:
         | OCaml is statically typed functional programming language. It's
         | a cousin of Haskell. It has some nice things like automatic
         | type inference so you don't have to write very many type
         | annotations. It's not as focused on purity as Haskell so its
         | easier to mutate state where you want to but you get a lot of
         | the niceties of ML programming languages like pattern matching,
         | variants, structural typing in places.
         | 
         | It also has object-oriented features, though they aren't widely
         | used the attitude is something like OO is there if we need it
         | and we're definitely willing to use it in places that require
         | it.
         | 
         | Its pretty fast for a functional language and you could
         | probably get pretty far with it before you'd have to consider
         | using a real low level langauge.
         | 
         | The disadvantages I think are pretty uncontroversial: a smaller
         | community, not as many libraries, a bit of a fractured stdlib
         | and build situation and until now no multicore.
        
           | themulticaster wrote:
           | > It has some nice things like automatic type inference so
           | you don't have to write very many type annotations.
           | 
           | I'm not quite sure what you're going for here. The Hindley-
           | Milner type system Haskell is based on essentially does not
           | require any type annotations [1]. By convention, every top-
           | level declaration is annotated, but that is only for
           | documentation and clarity.
           | 
           | Or did you mean that in comparing OCaml and Haskell to other
           | (imperative) languages?
           | 
           | [1] There are a few buts that don't have much to do with the
           | argument, but I'll list them here anyway:
           | 
           | 1) Sometimes the type you end up with is too ambiguous and
           | you'll need type annotations: E.g. what is the type of the
           | term "2+3"? It is something like "Num a => a" (read: any type
           | that is roughly number-like), but that is not useful if you
           | want to run the program. _However_ , in practice you won't
           | need an annotation in almost all cases as long as some
           | function you work with restricts the type.
           | 
           | 2) Some Haskell extensions increase ambiguity in certain
           | cases.
        
             | Zababa wrote:
             | > Sometimes the type you end up with is too ambiguous and
             | you'll need type annotations: E.g. what is the type of the
             | term "2+3"?
             | 
             | I don't think your example works in the case of OCaml since
             | the signature of (+) is int -> int -> int. Basic operators
             | not being polymorphic is one of the specificities of OCaml.
        
           | dunefox wrote:
           | Also no unicode support which is a huge con.
        
             | rwmj wrote:
             | Please no. OCaml gets this exactly right - on the rare
             | occasion I want to do something Unicode-y I'll use
             | Camomile, and the rest of the time don't get in the way
             | with stupid language decisions (yes I'm looking at you
             | Python 3 and Ruby).
        
             | patrec wrote:
             | I'd take ocaml's unicode support over python's,
             | javascript's or java's any day of the week.
        
               | reom_tobit wrote:
               | Tangent, but I've never really understood what the issue
               | is with unicode support in various languages.
               | 
               | Does anyone have any idea why it's such a contentious
               | issue?
        
               | tialaramex wrote:
               | Unicode reflects a reality about human writing systems.
               | They are _very_ complicated. This is more or less
               | guaranteed to result in Unicode being contentious.
               | 
               | After all, it's obvious features _my_ native language has
               | are important and need to be first class APIs in the
               | standard library, while any features that language doesn
               | 't use has aren't important and the standard library
               | shouldn't be clogged up with anything so useless. Also
               | things that are easy to do for my preferred writing
               | system must be supported, if the easy way to implement
               | them doesn't work for some other widely used languages,
               | just ignore that, those people don't matter anyway.
        
               | chubot wrote:
               | Basically because there's 2 major ways to do it: the
               | Windows way and the Unix way (UTF-8). Unicode has the
               | concept of encodings and it doesn't tell you which one to
               | use.
               | 
               | The Unix way is winning on the web, and I think Microsoft
               | has made some moves toward UTF-8, but I don't understand
               | what they are exactly:
               | 
               | https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Window
               | s#W...
               | 
               | JavaScript and Java inherited the Windows way. Go and
               | Rust use the Unix way (and apparently OCaml too). Python
               | supports both which some say is a needless source of
               | complexity, but it is flexible if you know how to use it.
        
               | reom_tobit wrote:
               | Awesome, thanks for the info. Sent me down a rabbit hole
               | for a little bit.
        
               | chubot wrote:
               | In case you didn't already get it, this is a good and
               | readable summary:
               | 
               | https://www.joelonsoftware.com/2003/10/08/the-absolute-
               | minim...
        
               | reom_tobit wrote:
               | Amazing link, would highly recommend to anyone reading
               | this thread. Thanks again
        
               | dunefox wrote:
               | I don't know, I like working with strings.
        
               | patrec wrote:
               | I'd say the chances of someone enjoying working with
               | strings in say javascript or java and their code actually
               | working correctly over the range of possible inputs it is
               | intended to handle are pretty slim, but that may just be
               | my lack of imagination. Can you give an example of
               | something unicode related that would be pleasant in
               | javascript or java but really a pain in ocaml?
        
         | rwmj wrote:
         | I develop in OCaml from time to time, and it's pretty
         | practical. Separate compilation, makes small-ish binaries that
         | most people wouldn't know weren't written in C/C++, fast,
         | garbage collection reduces mental burden, easily call out to C
         | if you need to. We steer clear of the more complex language
         | features like functors because they confuse most programmers.
         | 
         | Here's an example of one very widely used production
         | application:
         | https://github.com/libguestfs/virt-v2v/tree/master/v2v
         | 
         | It fits a similar niche to Golang or C++, but unlike those it's
         | an enjoyable language to program in.
        
       ___________________________________________________________________
       (page generated 2021-05-13 23:01 UTC)