Snake case and js_of_ocaml

Hi, I would like to export to javascript a function named my_snake_case but
it seems that js_of_ocaml won’t let me do it: in the following sample, the function is truncated to ‘my_snake’, as if only one underscore was allowed.

File snake_case.ml:


let _ =
  Js.export_all
    (object%js
      method my_snake_case x y = x + y
    end)
$ ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx -linkpkg snake_case.ml -o snake_case.byte
$ js_of_ocaml snake_case.byte 
$ node
Welcome to Node.js v12.22.9.
Type ".help" for more information.
> require ("./snake_case.js");
{ my_snake: [Function] }
> 

This seems to be a bug with the ppx, as constructing the object manually works:
EDIT: @haochenx pointed out below that this is expected behavior for the ppx.

# open Js_of_ocaml.Js;;
# let my_obj = Unsafe.obj [||];;
val my_obj : 'a = <poly>
# Unsafe.set my_obj (string "my_snake_case") ();;
- : unit = ()
# export_all my_obj;;
- : unit = ()

then from JS:

> window.my_snake_case
< 0

I assume case is being elided since it’s a reserved keyword in JS (i.e. switch ... case).

Probably worth opening an issue here.

The method name my_snake_case will become my_snake in JavaScript if you use js_of_ocaml-ppx. This is a documented behavior (see the “Method name and underscore” section of The Js_of_ocaml library) and I usually name my snake cased methods and values some_method_js so the actual part of the name is preserved.

2 Likes

I tried with ab_cd_ef_gh and the resulting function is ab_cd_ef

Ah, I stand corrected! Will edit my post :slight_smile:

thanks! I was searching the doc but couldn’t locate it

Glad it helped!

To be honest this is quite confusing at first and I also struggled for hours when I began to use jsoo… Maybe the document could make it clear by repeating the explanation of this behavior more, especially in the page explaining library binding and the ppx itself? @hhugo

2 Likes

I agree this is quite likely a problem that will come up very quickly to users of jsoo, so it should be more prominently explained.

This occurs with the ##, ##. and object%js ppx’s. I just append an underscore, as in obj##some_method_. The same solution works to escape property identifier names which are ocaml keywords, as in F##new_, whenReady##then_ and so on.

Another option, encouraged by brr’s identifier convention is to prime them, obj##new'. These final underscores always leave me wanting for more, they look like typos to me :–)

(Though that likely doesn’t work for that particular ppx)