Live data from Hacker News

A deep dive into Multicore OCaml garbage collector

kcsrk.info

51–60 of 97 posts

Re: A deep dive into Multicore OCaml garbage collector

#51
post #47

Earlier quoted context omitted.

In Go you can just do "go doWork()" and the scheduler runs the function as a coroutine on some kernel thread, thus allowing your program to make use of all cores. The ability to just throw goroutines at the scheduler changes how you approach writing programs. For example, say you want to process an input that consists of lots of individual records. You can run the input stream in one goroutine, then spawn a bunch of…

In OCaml there is Lwt. It provides very light-weight cooperative threads. The context switches are very fast and composing cooperative threads allows the writing of highly asynchronous applications. For instance, in the versions of Go prior to 1.5 goroutines used to run on a single core. And as of 1.5 the variable GOMAXPROCS can be set to the number of cores. EDIT:clarify the difference between concurrency and parall…

Lwt looks nice, but also seems a lot more intrusive to me than, say, Go. It's based on promises (so it's very explicit), and if I remember correctly, in order to do any I/O you have to use the Lwt mechanisms instead of the standard ones (which block).

How does Lwt interact with third-party libs that aren't written to use Lwt? I know from Ruby that libevent-type stuff such as Eventmachine doesn't combine all that well with non-async code.

Go made a good call in making all I/O blocking. That means code is easy to read and write. It comes with downsides, such as that you have to use goroutines, but for most developers it's a more productive concurrency model. (Unfortunately there's no alternative; you can build a blocking system out of a non-blocking one with no overhead, but the opposite is not true. When I first started with Go I was surprised that you can't "select{}" on a file descriptor or socket, or indeed any custom implementation, in the same way that "range" is magical and only works on built-in types.)

Re: A deep dive into Multicore OCaml garbage collector

#52
post #2

OCaml has always intrigued me as something to learn, but it seems I always read equally as many reasons that it's not good, not ready, or why I should try Haskell instead. Does anyone have experience to say yay/nay on worthwhile learning, know of any companies using it heavily, or know of any large cleany written codebases from which to study?

You might find these Reddit threads interesting:

* OCamlers on Haskell - https://www.reddit.com/r/ocaml/comments/3ifwe9/what_are_ocam...

* Haskellers on OCaml - https://www.reddit.com/r/haskell/comments/3huexy/what_are_ha...

Re: A deep dive into Multicore OCaml garbage collector

#53
post #47

Earlier quoted context omitted.

In OCaml there is Lwt. It provides very light-weight cooperative threads. The context switches are very fast and composing cooperative threads allows the writing of highly asynchronous applications. For instance, in the versions of Go prior to 1.5 goroutines used to run on a single core. And as of 1.5 the variable GOMAXPROCS can be set to the number of cores. EDIT:clarify the difference between concurrency and parall…

Lwt looks nice, but also seems a lot more intrusive to me than, say, Go. It's based on promises (so it's very explicit), and if I remember correctly, in order to do any I/O you have to use the Lwt mechanisms instead of the standard ones (which block). How does Lwt interact with third-party libs that aren't written to use Lwt? I know from Ruby that libevent-type stuff such as Eventmachine doesn't combine all that well…

Another great concurrency library in OCaml is the Async library. It's very convenient compared to Lwt. You can find here how it behaves with I/O operations https://realworldocaml.org/v1/en/html/concurrent-programming...

Re: A deep dive into Multicore OCaml garbage collector

#54
post #46

Earlier quoted context omitted.

IMHO, it's not so much that as the ASCII operator galore. $, , the horrible lambda syntax... Sometimes it looks an opinionated Perl.

I don't know if you've worked with a production Haskell code base but it cannot be over stated what a poor decision operator overloading is. if they got rid of that it would immediately make Haskell an order of magnitude more practical

Haskell for hobby programming coupled with professional Perl experience gave me enough idea of what creative programmers could come up with in terms of ASCII art.

Re: A deep dive into Multicore OCaml garbage collector

#55

Earlier quoted context omitted.

OCaml has many of the good qualities people attribute to Go (simplicity, speed, relatively low-latency GC, well-engineered compiler&runtime) and none of the downsides. Its weakness is terrible support for multithreading (like CPython it has a global lock, such that only one thread can execute OCaml code at a time), but there's work in progress to fix that. Personally I'm of the opinion that if the developers had take…

People often don't like the syntax too much (which is why Facebook invented Reason). There are other weaknesses as well: - the stdlib is good for data structures and not much else, which in turn gave rise to at least three different stdlib extensions - it does not have typeclasses, so implementing a generic "to_string" for your data type is not a thing - it has some really unfortunate ideas like "universal compare" -…

There has been developments along some of these issues:

- jbuilder (https://github.com/janestreet/jbuilder) has markedly improved the build system story. Importantly, the community understands that this is an issue and is actively working towards making the situation better.

- Type declaration at the code level is optional. You could always annotate your code with types, and the type checker will ensure that the annotated types are compatible with the inferred ones. If you would like to know "what type is this 'e' variable", there is merlin (https://github.com/ocaml/merlin), which integrates with popular editors.

- Reg. typeclasses, there has been enormous amount of work put into modular implicits (http://ocamllabs.io/doc/implicits.html). It is likely to be the next major features in OCaml along with multicore.

Re: A deep dive into Multicore OCaml garbage collector

#56

Earlier quoted context omitted.

People often don't like the syntax too much (which is why Facebook invented Reason). There are other weaknesses as well: - the stdlib is good for data structures and not much else, which in turn gave rise to at least three different stdlib extensions - it does not have typeclasses, so implementing a generic "to_string" for your data type is not a thing - it has some really unfortunate ideas like "universal compare" -…

The community tends to shy away from classes, but using a method for to_string accomplishes your second point in a minimal way. let to_string stringer : string = stringer#to_string val to_string : -> string = I think there's also plenty of people who feel just as strongly about Reason syntax in the other direction.

I'm not particularly attached to Reason syntax myself, but there are some bits of OCaml syntax that do annoy me, such as the right-to-left direction for parametrized types ('a list instead of a more usual list 'a).

As for classes, well... They're not really used outside of specific situations (eg, UI widgets), so it's not really a terribly convenient solution (especially since, for a really useful to_string implementation, you would want the member fields of your class to also implement to_string, so that would mean objects everywhere).

Re: A deep dive into Multicore OCaml garbage collector

#57
post #19

I never managed to understand why so many people were apparently longering for multicore support. I just can't believe many are impatiently waiting for this feature to start using the ocaml language for some projects requiring multicore support, and I became impatient myself just to see what those projects are. In recent years where servers are to scale to many machines I found myself using less and less kennel threa…

The short answer is: single-core cpu performance is not going up much in the recent years. The core count is still increasing every year. That is why graphics cards still see a strong rise in total performance, their usual work load is inherently parallel.

For typical server tasks, like web serving, we can just run several processes. Unix is doing this for decades. But even web serving is often cpu bound, if your SQL query runs only on one cpu.

The obvious thing to make programs faster is, to utilize as many cpus as possible to perform the computations. There is no silver bullet, but the recent years brought quite some progress. Go makes it easy and cheap to spawn off goroutines, the channels and GC help to make this a reasonable concept. Functional programming languages are even a more obvious candidate for parallel execution, as they have no side effects.

Re: A deep dive into Multicore OCaml garbage collector

#58
post #47

Earlier quoted context omitted.

In OCaml there is Lwt. It provides very light-weight cooperative threads. The context switches are very fast and composing cooperative threads allows the writing of highly asynchronous applications. For instance, in the versions of Go prior to 1.5 goroutines used to run on a single core. And as of 1.5 the variable GOMAXPROCS can be set to the number of cores. EDIT:clarify the difference between concurrency and parall…

Lwt looks nice, but also seems a lot more intrusive to me than, say, Go. It's based on promises (so it's very explicit), and if I remember correctly, in order to do any I/O you have to use the Lwt mechanisms instead of the standard ones (which block). How does Lwt interact with third-party libs that aren't written to use Lwt? I know from Ruby that libevent-type stuff such as Eventmachine doesn't combine all that well…

With algebraic effect handlers (the concurrency story of multicore OCaml), you can write your I/O code in direct-style, but retain the advantage of non-blocking I/O. As such, you have the advantage of goroutines, but this is also an opt-in. The asynchronous I/O is implemented as a library and is not baked into the language, and hence you can write your own I/O library. For more details, see our recent draft paper: http://kcsrk.info/papers/system_effects_may_17.pdf.

Re: A deep dive into Multicore OCaml garbage collector

#59
post #55

Earlier quoted context omitted.

People often don't like the syntax too much (which is why Facebook invented Reason). There are other weaknesses as well: - the stdlib is good for data structures and not much else, which in turn gave rise to at least three different stdlib extensions - it does not have typeclasses, so implementing a generic "to_string" for your data type is not a thing - it has some really unfortunate ideas like "universal compare" -…

There has been developments along some of these issues: - jbuilder ( https://github.com/janestreet/jbuilder ) has markedly improved the build system story. Importantly, the community understands that this is an issue and is actively working towards making the situation better. - Type declaration at the code level is optional. You could always annotate your code with types, and the type checker will ensure that the an…

> jbuilder (https://github.com/janestreet/jbuilder) has markedly improved the build system story. Importantly, the community understands that this is an issue and is actively working towards making the situation better.

Well, that's good to know.

> Type declaration at the code level is optional. You could always annotate your code with types, and the type checker will ensure that the annotated types are compatible with the inferred ones. If you would like to know "what type is this 'e' variable", there is merlin (https://github.com/ocaml/merlin), which integrates with popular editors.

I am aware of that. I shouldn't have to use Merlin to read third-party code from github, and god forbid that you have to do code review on a "let's all rely on type inference" codebase in a web browser. I think Rust strikes the right balance here, by enforcing the use of type signatures at function boundaries (which also lets it offer world-class error messages).

> Reg. typeclasses, there has been enormous amount of work put into modular implicits (http://ocamllabs.io/doc/implicits.html). It is likely to be the next major features in OCaml along with multicore.

I know about implicits. I also know that multicore has been "just around the corner" for a few years now, this does not bode well for implicits (which have also been "in progress" for a long time). This also touches another issue with the OCaml maintainers: little in the way of information seems to filter down to the unwashed masses, and let us not speak of the word "roadmap"...

Re: A deep dive into Multicore OCaml garbage collector

#60
post #19

I never managed to understand why so many people were apparently longering for multicore support. I just can't believe many are impatiently waiting for this feature to start using the ocaml language for some projects requiring multicore support, and I became impatient myself just to see what those projects are. In recent years where servers are to scale to many machines I found myself using less and less kennel threa…

In Go you can just do "go doWork()" and the scheduler runs the function as a coroutine on some kernel thread, thus allowing your program to make use of all cores. The ability to just throw goroutines at the scheduler changes how you approach writing programs. For example, say you want to process an input that consists of lots of individual records. You can run the input stream in one goroutine, then spawn a bunch of…

Go doesn't really have a good shared memory story, either. Shared memory support exists, but it's not really any safer than in C or Java. If that were good enough, then Ocamlnet's netmulticore library would already fit the bill. But most people who want shared memory support want something that's both safer and higher level.

Go really is designed around message-passing as its primary means of coordination; the key part here is having nice abstractions, which is where Go's strengths lie and which revolve primarily around `select`. But writing higher-level abstractions over processes and FIFO channels isn't terribly hard, as long as you have serialization built in (which Python, Ruby, and OCaml all do).

Post reply on HN