44 Warning using Cmdliner

I am getting a 44 warning ( Warning 44: this open statement shadows the value identifier & (which is later used)

On all the CmdLiner.Arg. calls

I thought I pretty much copied the standard beginner example from CmdLiner. (see below).

I am seeing this in VSCode with Reason-VScode extension. Yes, I am using BuckleScript to compile (But this is before that). The compile works fine.

I have a standard bsconfig file, and I would like to see the warnings, and not suppress ones like this if I can fix it.

    (* OCaml syntax *)
    open Cmdliner
    [%%raw "process.argv.shift()"]

    let chorus count msg =
      for i = 1 to count do print_endline (msg ^ string_of_int i) done

    let count =
      let doc = "Repeat the message $(docv) times." in
      Arg.(value & opt int 10 & info ["c"; "count"] ~docv:"COUNT" ~doc)

    let msg =
      let doc = "Overrides the default message to print." in
      let env = Arg.env_var "CHORUS_MSG" ~doc in
      let doc = "The message to print." in
      Arg.(value & pos 0 string "Revolt!" & info [] ~env ~docv:"MSG" ~doc)

      let chorus_t = Term.(const chorus $ count $ msg)

      let info =
      let doc = "print a customizable message repeatedly" in
      let man = [
        `S Manpage.s_bugs;
        `P "Email bug reports to <hehey at example.org>." ] in
      let version = "0.0.1" 
      Term.info "chorus" ~version ~doc ~exits:Term.default_exits ~man

    let () = Term.exit @@ Term.eval (chorus_t, info)

This is just a warning, not a big reason to worry about. It is disabled by default, by the way. You can disable it, if you want, globally (using your build configuration - I don’t know how it is done in bs, though), or you can disable it locally using the [@@warnings "-44"] attribute.

The warning itself is saying: “hey, this open statement changes the meaning of an identifier, be careful, some of your code that used to work before you add this open may stop working or work differently”. Most likely it is about the Arg module which is also present in the standard library.

[@@warnings “-44”]

gives me a syntax error both in vscode and when I go to compile with BSB

yes, I know how to turn off the warnings in the bsconfig.json , I think what you are telling me is that the problem is in the Cmdliner package (or at least, using Open and there are no "qualfiiers (I come from Haskell) for the namespace for Args, so there is no simple fix on my side, but rather this has to be done in the package. I would expect there is a way to add the namespace, and not make a conflict.

This attribute is attached to the module item, so that it will be attributed only to the attached open statement, e.g.,

open Cmdliner [@@warning "-44"] (* its ok to shadow Arg here *)

You can also disable warnings on the scope of the whole file, by adding

[@@@warning "-44"]

And in the code that follows this attribute will no longer trigger that warning.

Nope, that is not what I am telling you. I’m telling you that there is no problem (except that for some reason someone decided to enable this warning by default). There are lots of different warnings, that raise lots of discussions about their usefulness. And as with any warning or lint rules, there are many false positives, when a problem is raised in cases when there are no problems. So nothing has to be fixed.

Just in case, if you need the hidden Arg module, just alias it to some other name, before opening Cmdliner, e.g.,

module OldArg = Arg
open Cmdliner

Also, you don’t need to open a module namespace to be able to use it, unlike Haskel or Python, open doesn’t import anything. It just allows you to use definitions in the opened module without qualification.

Finally, if you want both explicitness and conciseness, you can use local opens on both expression and definition level, e.g.,

let my_func_that_uses_cmldiner () = 
   let open Cmdliner in  
   (* the rest of the code, where you can reference `Cmdliner.Arg` just as `Arg` *)

or like this

let my_other_func () =
   Cmdliner.(.... Arg.value  ...)

Or, on the module level,

include struct 
  open Cmdliner
  (* from here and until the end we can use Arg without qualification *)


Apparently, you’re getting these warnings not on open Cmdliner, but on Arg.(value & opt int 10 & info ["c"; "count"] ~docv:"COUNT" ~doc), which says that the & operator is hidden by this local open. Again, there are no worries, this is an absolutely conventional usage of local opens, when an opened module shadows operators and names from some algebra. It is used for embedded DSLs and for making your program more readable.

I’m advising you to disable this warning. Either on the level of the file (with [@@@warning "-44"]) or, which is better, in the build system. This warning will only annoy you and rarely if ever, will indicate a real error.

1 Like

Yea, all the Open, global and other pre-processor switches did not work for BSB. but I did add the +44 to the bsconfig and that stopped the warnings. (Not in Vscode, the plugin still needs to be configured).

It is not a preprocessor switch, it is a part of the language, so it should work. I’ve tried on BS playground and it works. Well, at least I don’t get the parsing errors, though the item-level attribute is ignored, but the global level works and hushes the warning, e.g.,

[@@@warning "-44"]
let say_hello () = "Good bye!"

module Shadower = struct 
  let say_hello () = print_endline "Hello!"

open Shadower

let () = say_hello ()

is successfully translated to

> Hello!
'use strict';
function say_hello(param) {
  return "Good bye!";
function say_hello$1(param) {
  return /* () */0;
var Shadower = /* module */[/* say_hello */say_hello$1];
exports.say_hello = say_hello;
exports.Shadower = Shadower;
/*  Not a pure module */

Also, to disable a warning you need to precede its number with the minus sign (-), not with +, which on a contrary, enables a warning,

  "warnings": {
    "number": "-44-102",
    "error": "+5"