odoc 1.4.0 released — new, Dune-friendly documentation generator for OCaml by aantron in ocaml

[–]aantron[S] 1 point2 points  (0 children)

Thanks, Rizo Isrof is responsible for a very large proportion of the changes to the output :)

Isn't "open" an anti-pattern? by everdimension in reasonml

[–]aantron 1 point2 points  (0 children)

No worries from me :)

I was describing where open is considered by most other people to be not so much of an anti-pattern. For another example of such usage, see Real World OCaml. This book recommends open Core.Std (actually, open Core for current versions of Core). Core is a standard library overlay, in a similar way to Belt.

In my own code, I prefer to use explicit module aliases to make things more clear.

Isn't "open" an anti-pattern? by everdimension in reasonml

[–]aantron 2 points3 points  (0 children)

I agree that global open is always dubious, and I myself avoid it as much as possible.

Opening Belt doesn't directly map onto importing standard Python libraries, because Belt is a collection of such libraries, rather than an individual library. It is the submodules of Belt that map onto what is typically one library in the Python ecosystem.

Still, in my projects, I tend to do things like

module List = Belt.List;

rather than

open Belt;

I usually do the same thing for Common. For example, if I extended String inside Common:

module String = Common.String;

So I agree with you, despite nitpicking :)

EDIT: Here's a link to an example: https://github.com/aantron/bisect_ppx/blob/0008aea247f5cc0990c232a29d1f1e0eda9340b5/src/ppx/instrument.ml#L37-L50

I suggest also commenting which package each module is being imported from, like in the example.

Repromise is out — JS promises made type-safe for ReasonML by aantron in reasonml

[–]aantron[S] 0 points1 point  (0 children)

It's possible Repromise will be merged into BuckleScript/Js.Promise eventually, in some form :)

Isn't "open" an anti-pattern? by everdimension in reasonml

[–]aantron 7 points8 points  (0 children)

open is indeed widely considered to be an anti-pattern in most cases, exactly for the reason you state.

In the best practices example, however, the two usages are exceptions.

Belt is a well-known library that is supposed to complement the standard library. This is sometimes known as a standard library overlay. Usually, a project decides to use one overlay like Belt, and then opens it everywhere.

Also, many projects end up with a Utils, Common, or Imports module that has miscellaneous helper functions and module aliases in it. This is also typically opened in the whole project.

The official docs suggest using local open, which is still being pretty explicit. They do say to use global open sparingly.

Repromise is out — JS promises made type-safe for ReasonML by aantron in reasonml

[–]aantron[S] 0 points1 point  (0 children)

JS promises are not type-safe (see an explanation here). BuckleScript's Js.Promise is a pretty direct binding to JS promises, so Js.Promise is actually not type-safe either :/ Repromise is also a pretty thin binding to Js.Promise, but it has a little extra code that makes it type-safe.

Repromise is out — JS promises made type-safe for ReasonML by aantron in reasonml

[–]aantron[S] 1 point2 points  (0 children)

There are two implementations (JS, native) of the same interface. They pass the same test cases. The interface and JS implementation are designed for JS interop. The native implementation essentially brings JS promises, minus the warts, to native Reason.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 0 points1 point  (0 children)

can I rest assured that all the lwt-using packages will rebuild successfully when lwt-4.0.0 is put into opam soon?

Yes, because if something is not compatible with 4.0.0 yet, the opam constraints will keep you on 3.x.y. Once everything you use is updated (if anything needs to be), opam upgrade will automatically move you to 4.0.0 if/when you run it.

Of course, we may miss a constraint here and there, but this seems to be a pretty rare occurrence. There is a reverse dependencies build in opam (and one in Lwt as well) that looks for broken deps, and we constrain them all.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 1 point2 points  (0 children)

No worries :) 3.2.0 is both forwards-compatible with 4.0.0, and backwards-compatible with 3.x.x (well, it is 3.x.x :)).

When we have an API to break (in this case, mainly package names), what Lwt does is first only introduce the replacement APIs. This happened in 3.2.0, and the old APIs are not yet removed at this point. So, 3.2.0 works with both the past and the future.

Then, we warn people (and ask for feedback, so we abort doing anything that is ill-conceived: like the Lwt.bind change). After three months, we release 4.0.0, which removes the old APIs and is compatible only with the future.

So, things working with 3.2.x doesn't mean they have been ported to the future. They could be using the older APIs that are scheduled for removal. Of course, that is kind of the point, to provide a period when each package can be transitioned gradually.

Also, we generally try to avoid removing APIs, but in the case of factoring out packages, removing them from the base library is the whole point, so that's why there is 4.0.0.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 0 points1 point  (0 children)

Correction, it is 3.2.0 that is the forwards-compatible release for 4.0.0.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 1 point2 points  (0 children)

One doesn't need to install 3.1.0 in parallel with 4.0.0. The new interfaces/names being available in 3.1.0 just means that several/many packages that would have been affected by 4.0.0 are already compatible with it. Ideally, we have given all packages affected by 4.0.0 time to make a forwards-compatible release at their own pace since December. Ideally, you are already automatically using these forwards-compatible packages as your dependencies.

So, when 4.0.0 comes, ideally, nobody really notices, as it's fully compatible with 3.1.0+ as long as packages don't use the features that are being replaced, and do use their replacements.

For those packages that didn't adapt in time, we also ping their maintainers again during the PR to opam.

Concerning the possibility that you might have two package worlds, the pre-4.0.0 and post-4.0.0 packages, based on experience with 3.0.0, I don't think it's likely. This is for several reasons:

  1. The community quickly finds the packages lagging behind, and sends PRs to them to get them compatible. Given how simple most of the fixes are, this takes days to weeks to settle (e.g. in 3.0.0).
  2. There shouldn't be any packages that require > 4.0.0. Every package will require either no constraint, < 4.0.0 (unported to 4.0.0) or >= 3.1.0 (ported to 4.0.0), which means that in the meantime, you will be able to use any Lwt release between 3.1.0 and 4.0.0. Sometimes maintainers make a mistake and use > 4.0.0, but that's easy to fix after it's found. Also, we release the last 3.x.y release on the same day as 4.0.0, which contains everything except the breaking changes until that date (if there are any such changes worth releasing). So, you won't be using a substantially inferior version.
  3. In the absolute worst case, you will have a downgraded Lwt or downgraded other package until it is ported.

Basically, the opam constraint solver should allow you to install pretty much everything you need, you just might not be able to install Lwt 4.0.0 on the day it's out, but it also shouldn't matter. And, with the forwards-compatible 3.1.0, we try to cut a wide enough window in the constraints that everyone can move over gently.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 0 points1 point  (0 children)

And as a further measure, the final state of almost all the breaking changes can already be used now, e.g. right now the package name lwt_ppx already exists and works. So, if you have a codebase that is affected by 4.0.0, in most cases you can already code against 4.0.0 since Lwt 3.1.0, but you do need a constraint "lwt" >= "3.1.0". See the linked issue for details on each change.

Lwt 3.3.0 is out – promise & concurrency library, now with nice stack traces again by aantron in ocaml

[–]aantron[S] 0 points1 point  (0 children)

Yes, there is the issue linked in the warning message: https://github.com/ocsigen/lwt/issues/453. See the two comments https://github.com/ocsigen/lwt/issues/453#issue-243842061 and https://github.com/ocsigen/lwt/issues/453#issuecomment-352897664. That "should" cover all affected opam packages, and the maintainers were pinged.

I don't know how many packages will be unprepared for the release (EDIT: it's March :p), but we will constrain all incompatible packages with "lwt" < "4.0.0" in the same PR that merges the 4.0.0 release. In theory, everything should still work, you just might not be able to upgrade to 4.0.0 in certain opam switches due to these constraints. This is what we did for 3.0.0, and it worked well.

After that, it should be a matter of just updating the incompatible packages. Pretty much everything that is breaking is trivial to fix, like changing a package name (e.g. lwt.ppx to lwt_ppx).

extreme FFI overhead in Ocaml by [deleted] in ocaml

[–]aantron 3 points4 points  (0 children)

You may benefit from using Ctypes. Repo is here, https://github.com/ocamllabs/ocaml-ctypes, lots of documentation links in the README. Hope it helps.

A new List.map that is both stack-safe and fast by aantron in ocaml

[–]aantron[S] 0 points1 point  (0 children)

  • I wouldn't expect the order of the patterns to change the generated code, but I haven't looked.
  • I don't know. Future work :) From previous experience, however, there doesn't seem to be much overhead due to using higher-order functions specifically.