I had never taken the time to learn OCaml but Reason does indeed feel more accessible to me. Thank you for contributing to make OCaml easier for people like me! I'm using the weekend to get started and trying to follow Real World OCaml examples with Reason syntax. I've been unable to open Core.Std. Here's the question I wrote in StackOverflow:
I'm new to OCaml and I'm trying to try (:P) Facebook Reason syntax. I cannot find a way to make this compile because if cannot find the Core module (already installed with opam).
I'm trying to compile a sample program from Real World OCaml
open Core.Std;
let rec read_and_accumulate accum => {
let line = In_channel.input_line In_channel.stdin;
switch line {
| None => accum
| Some x => read_and_accumulate (accum +. Float.of_string x)
}
};
let () = printf "Total: %F\n" (read_and_accumulate 0.);
This is the command I'm using for compilation: rebuild accum.native.
When I have this in _tags (from the instructions in https://janestreet.github.io/installation.html)
true: package(core,ppx_jane)
true: thread,debug
My error changes but I still don't know what to do:
File "_tags", line 1, characters 6-28:
Warning: tag "package" does not expect a parameter, but is used with parameter "core,ppx_jane"
File "_tags", line 1, characters 6-28:
Warning: the tag "package(core,ppx_jane)" is not used in any flag or dependency declaration, so it will have no effect; it may be a typo. Otherwise you can use `mark_tag_used` in your myocamlbuild.ml to disable this warning.
+ /Users/David/.opam/4.02.3/bin/ocamldep.opt -modules -pp refmt -impl accum2.re | tee accum2.re.depends accum2.ml.depends
accum2.re: Core Float In_channel
+ /Users/David/.opam/4.02.3/bin/ocamlc.opt -c -g -thread -pp '-g -thread' -pp refmt -o accum2.cmo -intf-suffix .rei -impl accum2.re
File "accum2.re", line 1, characters 5-13:
Error: Unbound module Core
Command exited with code 2.
Compilation unsuccessful after building 2 targets (0 cached) in 00:00:00.
What do I have to do to use Core with Reason?
Adopting the syntax is pretty easy and I have only been reading for a couple hours, but there's zero docs about how to use Reason for non OCaml users.
I posted this in http://stackoverflow.com/questions/37504534/how-to-use-jane-streets-core-with-reason so it would be helpful if you reply there, otherwise I'll copy any help received here :)
Thank you for your patience with respect to using and forming dependencies on external packages at build time. This is something we want to make easier as a next step (keep an eye on jengaboot for a better long term solution).
@yunxing Likely knows the answer to your immediate question.
Adopting the syntax is pretty easy and I have only been reading for a couple hours, but there's zero docs about how to use Reason for non OCaml users.
Yes! I totally agree. On the Reason landing page, you'll see that there are three main "pillars" of Reason: Syntax, Build, Share. The Build and Share items are faded out as a sort of acknowledgment of what you've observed, and conveying our intent to eventually "fill them in". I hope @yunxing knows the answer to your question to unblock you in the short term though.
We're hoping that eventually, you'll just be able to make a package.json with an entry for "Core": versionNumber and then everything will just magically work.
@jordwalke thanks for the reply. I'm not sure about the .json part, but sound good that you are thinking about it. Hopefully @yunxing can help met out, I didn't understand how to use jengaboot to solve the issue. :)
@davidpelaez I'm developing jengaboot a bit silently. If you want, jump on #reasonml in free node and ping me =)
In theory I thought you could do something like this:
/* Hello.re */
open! Core.Std;
let rec read_and_accumulate accum => {
let line = In_channel.input_line In_channel.stdin;
switch line {
| None => accum
| Some x => read_and_accumulate (accum +. Float.of_string x)
}
};
let () = printf "Total: %F\n" (read_and_accumulate 0.);
rebuild Hello.native -pkg core
This gives me:
Error: No implementations provided for the following modules:
Thread referenced from /Users/me/.opam/4.02.3/lib/core/core.cmxa(Core)
Mutex referenced from /Users/me/.opam/4.02.3/lib/core/core.cmxa(Core)
Condition referenced from /Users/me/.opam/4.02.3/lib/core/core.cmxa(Core)
Event referenced from /Users/me/.opam/4.02.3/lib/core/core.cmxa(Core)
Command exited with code 2.
I tried it the CommonML way, but this gives me
ocamlfind: Error from package 'threads': Missing -thread or -vmthread switch.
This apparently a known issue:
https://github.com/jordwalke/CommonML/issues/10
I'll try Jenga later this evening, hopefully I'll have more success 馃槃
rebuild accum2.native -use-ocamlfind seem to bring it a little forward, but I don't have any experience with OCaml so I cannot find a way to see anything useful for debugging purposes in the following output:
+ ocamlfind env OCAMLOPT="ocamlopt.opt" /Users/David/.opam/4.02.3/bin/reopt -c -g -thread -package core,ppx_jane -pp '-g -thread -package core,ppx_jane' -pp refmt -o accum2.cmx -intf-suffix .rei -impl accum2.re
Usage: ocamlfind query [-help | other options] <package_name> ...
or: ocamlfind ocamlc [-help | other options] <file> ...
or: ocamlfind ocamlcp [-help | other options] <file> ...
or: ocamlfind ocamlmklib [-help | other options] <file> ...
or: ocamlfind ocamlmktop [-help | other options] <file> ...
or: ocamlfind ocamlopt [-help | other options] <file> ...
or: ocamlfind ocamloptp [-help | other options] <file> ...
or: ocamlfind ocamldep [-help | other options] <file> ...
or: ocamlfind ocamlbrowser [-help | other options]
or: ocamlfind ocamldoc [-help | other options] <file> ...
or: ocamlfind install [-help | other options] <package_name> <file> ...
or: ocamlfind remove [-help | other options] <package_name>
or: ocamlfind printconf [-help] [variable]
or: ocamlfind lint [-help] <file>
or: ocamlfind list
or: ocamlfind pkg/cmd arg ...
Select toolchain with:
ocamlfind -toolchain <t> <command>
Abbreviations:
e.g. ocamlfind opt instead of ocamlfind ocamlopt
Command exited with code 2.
Compilation unsuccessful after building 3 targets (2 cached) in 00:00:00.
After a lot of help from @chenglou I could figure out how to do it. Basically the _tags indicated in https://janestreet.github.io/installation.html have to be added _and_ three more flags and values: -linkpkg (I assume for static linking), -pp refmt indicating the ReasonML preprocessor and -impl file.re to tell what file to load. So if I have this file accum.re:
open Core.Std;
let rec read_and_accumulate accum => {
let line = In_channel.input_line In_channel.stdin;
switch line {
| None => accum
| Some x => read_and_accumulate (accum +. Float.of_string x)
}
};
let () = printf "Total: %F\n" (read_and_accumulate 0.);
I can compile it to a native binary with:
ocamlfind ocamlc -g -thread -package ppx_jane -package core -pp refmt -linkpkg -o accum.native -impl accum.re
I would like to use ocamlbuild but I couldn't find a way to set the impl flag through an ocamlbuild command. I can leave this open until I figure it out with ocamlbuild and/or rebuild as well.
@davidpelaez Thank you for sharing your solution so others can use it!
Hi @davidpelaez, just got back to town. Thanks for checking out Reason.
You actually helped us to discover a bug in rebuild -- rebuild doesn't work with -use-ocamlfind!
First of all, here are some contexts about how rebuild works:
rebuild is a wrapper of ocamlbuild. It changes ocamlbuild by replacing all the calls to ocamlopt with reopt. Now what is reopt? reopt is a wrapper of ocamlopt which passes in correct flags so it understands reason.

What's the problem here?
After a package is installed, one needs to call ocamlbuild with -use-ocamlfind so the build system can find out where the installed package is. The command that is called by ocamlbuild becomes something like ocamlfind ocamlopt -package core ... (Like what you've been using).
However, remember we just replaced all the calls to ocamlc with reopt? The command above then becomes ocamlfind reopt -package core ... -- and ocamlfind doesn't understand that!
The fix?
Instead of changing the subcommand from ocamlfind ocamlopt to ocamlfind reopt, we should use the recommend way in their manual: Change an environment variable env OCAMLFIND_COMMANDS=="ocamlc=$REOPT" to modify the behavior of ocamlfind.
I'm going to submit a fix about this soon.
maybe this is somehow related.
I am using https://github.com/reasonml/ReasonNativeProject to start a native reason project and i hit the same error when i try to add core to opam config file.
位 ~/GitHub/rejq/ master* make
cp pkg/META.in pkg/META
ocamlbuild -package topkg pkg/build.native
Finished, 4 targets (0 cached) in 00:00:00.
./build.native build
+ ocamlfind ocamlc -c -package menhirLib -package cmdliner -package core -package yojson -pp '-package menhirLib -package cmdliner -package core -package yojson' -I src -pp 'refmt --print binary' -o src/rejq.cmo -intf-suffix .rei -impl src/rejq.re
ocamlfind: Error from package `threads': Missing -thread or -vmthread switch
Command exited with code 2.
Compilation unsuccessful after building 2 targets (0 cached) in 00:00:00.
build.native: [ERROR] cmd ['rebuild' '-use-ocamlfind' '-I' 'src' '-pkg' 'yojson' '-pkg' 'core'
'-pkg' 'cmdliner' '-pkg' 'menhirLib' 'opam' 'pkg/META' 'pkg/META'
'src/rejq.native']: exited with 10
make: *** [build] Error 1
this time I cannot easily pass in the -thread opt because the build process is somewhat tightly controlled by https://github.com/reasonml/ReasonNativeProject/blob/master/pkg/build.ml
The solution @Jimexist is looking for (and anyone else is looking for) is the -tag option for rebuild that passes tags to ocamlc. So the common one is -tag thread. For the makefile provided in the ReasonNativeProject, this looks like
.PHONY: all clean byte native profile debug test
OCB_FLAGS = -use-ocamlfind -tag bin_annot -tag thread -pkg core
OCB = rebuild $(OCB_FLAGS)
all: byte # profile debug
...
This question will probably get more discussion in the reasonml forums -- https://reasonml.chat/
Most helpful comment
After a lot of help from @chenglou I could figure out how to do it. Basically the _tags indicated in https://janestreet.github.io/installation.html have to be added _and_ three more flags and values:
-linkpkg(I assume for static linking),-pp refmtindicating the ReasonML preprocessor and-impl file.reto tell what file to load. So if I have this fileaccum.re:I can compile it to a native binary with:
ocamlfind ocamlc -g -thread -package ppx_jane -package core -pp refmt -linkpkg -o accum.native -impl accum.reI would like to use ocamlbuild but I couldn't find a way to set the
implflag through anocamlbuildcommand. I can leave this open until I figure it out with ocamlbuild and/or rebuild as well.