Confusing OCaml Base/Core library deprecation warnings - ocaml

I've been trying Jane Street's Base / Core libraries for a few hours now, and I got very confused by depracation warnings.
With the following code:
open Base
(* open Core *)
open Stdio
let _ = printf "%d" (4 mod 3)
I get a deprecation warning:
Alert deprecated: Base.mod
[2016-09] this element comes from the stdlib distributed with OCaml.
Use (%), which has slightly different semantics, or Int.rem which is equivalent.
I get that I have to use % or Int.rem, but when I simply open Core, the warning disappears.
The documentation doesn't seem to clarify much regarding these 'deprecations'.
Also, with the following code:
(* open Base *)
open Core
(* open Stdio *)
let _ = Out_channel.output_string stdout "Hello, OCaml"
let line = In_channel.input_line_exn stdin
I get
Alert deprecated: Core.stdin
[since 2016-04] Use [In_channel.stdin]
but surprisingly, no alert for stdout.
When I uncomment the (* open Stdio *) line, I no longer get warnings.
I can guess that Stdio module is probably shadowing the stdin/stdout, but I thought open Core was enough for this as it depends on the Stdio module.
I used
ocamlfind ocamlopt -o output.out -linkpkg -package base,stdio -thread output.ml
and with -package base,stdio, respectively.
Why am I not getting a deprecation warning for 'mod' when I use open Core, if it warned me if I used open Base?
Why am I getting no alert for stdout?
2-1. Is it normal necessary to open Stdio as well when I open Core?

Related

How to disable Error (warning 66): unused open! in dune

As per https://github.com/ocaml/ocaml/pull/1110, OCaml 4.08 and later raises a warning for unused module opens, even when they are opened with open!. This creates friction with the common practice of using open! Foo to establish that the following code is to be in the context of module Foo (whether or not any thing is used from inside of Foo). Moreover, since dune treats all warnings as fatal errors by default, this will cause dune builds in the default dev profile to fail with errors like
$ dune build
File "lib/mylib.ml", line 1, characters 0-10:
1 | open! Core
^^^^^^^^^^
Error (warning 66): unused open! Core.
How can I disable this warnings and the fatal error?
The dune FAQ explains how to configure warnings so that they are "non-fatal" (letting the build proceed). However, this will still leave the warnings cluttering your build output. For developers using the open! Foo idiom to establish the context, this is annoying. The best solution is just to selectively disable this warning for the project:
Create a dune file at the root of your project
Add the following stanza
(env
(dev
(flags (:standard -w -66))))
This stanza instructs dune to pass the -w flag with the -66 argument to the OCaml compiler when building under the dev profile. man ocamlc explains how this flag works:
-w warning-list
Enable, disable, or mark as fatal the warnings specified by the argument warning-list.
...
-num Disable warning number num.
...
The warning numbers are as follows.
...
66 Unused open! statement.

Frama-C Aluminum "Unbound module GMenu"

On Fedora 21, I compiled the Frama-C Aluminum distribution from source after installing all its prerequisites. My version of OCaml is 4.02.3. Frama-C and the Frama-C GUI work fine. I am trying to follow section 2.3, "The ViewCfg plug-in" of the Frama-C Plug-In Development Guide. However, in section 2.3.4, "Extending the Frama-C GUI", after I add the GUI extension code and run it using the "-load-script" option, I get the following message:
File "cfg_print.ml", line 87, characters 19-43:
Error: Unbound module GMenu
[kernel] user error: compilation of 'cfg_print.ml' failed
Lines 86-87 read:
let cfg_selector
(popup_factory:GMenu.menu GMenu.factory) main_ui ~button:_ localizable =
I googled "unbound module gmenu" but didn't find anything useful. I also never ran into this error while using the Neon and Sodium versions of Frama-C. Interestingly, if I skip that section and follow section 2.3.5, "Splitting files and writing a Makefile", I no longer get the "Unbound module GMenu" message, and the example works fine.
If I had to guess, when I use the "-load-script" option, Frama-C (or my version of OCaml, whatever the case may be) apparently cannot find the Gtk libraries for some reason. But if I use make, OCaml can find the Gtk libraries. Is there something possibly wrong with the way I installed Frama-C and/or the Gtk libraries? How can I check this, or more importantly, how can I fix this?
Your Frama-C installation is probably ok. What you observe is a bug that was introduced when we transitioned to OCamlfind. We will fix it for Frama-C Silicium.
In case you really want to use a script, here is the patch that you need to apply to the sources of Frama-C:
--- a/src/kernel_services/plugin_entry_points/dynamic.ml
+++ b/src/kernel_services/plugin_entry_points/dynamic.ml
## -236,7 +236,7 ## let load_script base =
else
Format.fprintf fmt "%s -c" Config.ocamlc ;
Format.fprintf fmt " -w Ly -warn-error A -I %s" Config.libdir ;
- if !Config.is_gui then Format.pp_print_string fmt " -I +lablgtk" ;
+ if !Config.is_gui then Format.pp_print_string fmt " -package lablgtk2" ;
List.iter (fun p -> Format.fprintf fmt " -I %s" p) !load_path ;
Format.fprintf fmt " %s.ml" base ;
Format.pp_print_flush fmt () ;

Compiling program that uses Lwt_term

I have the following code in OCaml:
open Lwt
open Lwt_term
let () = Lwt_main.run (
lwt l = Lwt_read_line.read_line ~prompt:[text "foo> "] ())
when I try to compile using
ocamlfind ocamlc -package lwt cli.ml - o cli.byte
it I get the following error:
File "cli.ml", line 2, characters 0-13:
Error: Unbound module Lwt_term
I know it's unrelated to the problem above, but from utop I can open Lwt but I still can't open Lwt_term. What am I doing wrong?
Source file is located there so I bet that you need lwt.text package
Not really a real answer to the original question, but I have ended up using Core to accomplish it. The enlightenment came from finding the readline_test.ml file in a tests folder in the Core library (https://github.com/janestreet/core_extended/blob/master/lib_test/readline_test.ml).
Following that example it was really easy to implement readline-like functionality.

OCamlbuild fails to compile complaining implementation of Netsys is not provided when it is

I'm trying to compile an XML-RPC server written using the xmlrpc-light library in OCaml with ocamlbuild but I get:
$ ocamlbuild server.native
Finished, 0 targets (0 cached) in 00:00:00.
+ ocamlfind ocamlopt -linkpkg -package xmlrpc-light -package unix -package threads -package netsys -thread server.cmx -o server.native
File "_none_", line 1, characters 0-1:
Error: No implementations provided for the following modules:
Netsys referenced from /usr/lib/ocaml/equeue/equeue.cmxa(Uq_engines)
Command exited with code 2.
Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.
Note that I have a myocamlbuild.ml file like this one and a _tags file containing a single line:
<server.ml> or <server.native>: pkg_unix,pkg_netsys,pkg_xmlrpc-light,pkg_threads
This plugin has worked fine for me in other cases (for client.native of the same client/server application, for example) but not for server.native. The complaint suggests that the library Netsys is not available to the compiler. But we get
$ ocamlfind query netsys
/usr/lib/ocaml/netsys
meaning that netsys is installed in /usr/lib/ocaml/netsys. Inspecting that directory gives me:
$ ls /usr/lib/ocaml/netsys
META libnetsys.a netsys.a netsys.cma netsys.cmi netsys.cmxa netsys.mli
Also,
$ ocamlfind list | grep netsys
netsys (version: 2.2.9)
So, there is indeed a library called netsys installed, it does have a cmxa file ready to be used, but for some strange reason, ocamlbuild complaints that there is no implementation provided for the module Netsys. The fact that ocamlbuild could read /usr/lib/ocaml/equeue/equeue.cmxa should be enough to conclude that everything should be fine regarding environment ($PATH, etc.) in terms of finding libraries.
This is all in Debian 6.0 and my OCaml's version is 3.11.2.
After some browsing, I found an svn commit message (repository diff) which suggests that it may have to do with the number of threads used. And, in fact, I'm using a Mutex somewhere in my code (check the code of server.ml and client.ml in this other question). If I remove the Mutex stuff from my server.ml the error still happens. But if I additionally remove the pkg_threads from the _tags file then everything compiles. So, my conclusion is that I can't directly use the threads library with xmlrpc-light, which is weird.
IMHO equeue META is wrong. Adding netsys to dependencies fixes your issue :
sed -i 's/threads/netsys,threads/' /usr/lib/ocaml/equeue/META

Regular Expressions in OCaml

I want to use regexps in OCaml and it seems that Str module provides these functionalities.
So I tried with a simple program:
open Str
let regx = regexp "."
but it gives me the following error
File "lol.ml", line 1, characters 0-1:
Error: Error while linking lol.cmo:
Reference to undefined global `Str'
As if module is not present but if I remove open Str it says that regexp is an unbound value.
I don't get what kind of issue it is, Str should be a standard module (according to http://caml.inria.fr/pub/docs/old-311/libref/Str.html) so I'm clueless.. the only think I thought is that signature (mli) is present but implementation (ml) is not.
I'm running Objective Caml version 3.11.0 according to ocaml tool.
Can anyone help me figuring this out?
Thanks in advance
From the manual:
Programs that use the str library must be linked as follows:
ocamlc other options str.cma other files
ocamlopt other options str.cmxa other files
Or you can put
#load "str.cma";;
if you are doing it in the interpreter
As an alternative to the Str module there's also Re2.
Install it using opam install re2
Use the module in your_file.ml like this:
open Re2.Std
open Re2.Infix
let change input_text = Re2.rewrite_exn ~/"change this" "to that" input_text
let () = printf "%s" (change "change this")
Compile with ocamlbuild -use-ocamlfind -package re2 -package core -tag thread your_file.byte