Ocaml brr: getting all the props/keys of an object

For building/constructing objects, we have this line here: https://github.com/dbuenzli/brr/blob/master/src/jv.ml#L51

external obj : (prop * t) array → t = “caml_js_object”

Now, my question is: how do we deconstruct objects? I.e. get a list of all the keys, or a list of all (prop * t) ?

Thanks!

I suggest you spend some quality time with Brr’s FFI docs. You have a whole manual and a cookbook to peruse which have all the details.

I eventually solved this, via:

let obj_keys (obj : Jv.t) : string list =
  List.map ~f:(fun x -> Jstr.to_string x) @@ Jv.to_jstr_list @@ Jv.call (Jv.get Jv.global "Object") "keys" [| obj |]

let obj_pairs (obj : Jv.t) : (string, Jv.t) Hashtbl.t =
  let keys = obj_keys obj in
  Hashtbl.of_alist_exn (module String) @@ List.map ~f:(fun k -> (k, Jv.get obj k)) keys

however, not via the FFI/Cookbook links

If we start with brr/jv.ml at master · dbuenzli/brr · GitHub , what I was hoping for was either:

  1. finding a function with type (prop * t) array or a function w/ name keys ( Object.keys() - JavaScript | MDN ) , but neither was in the jv.ml file

  2. grepping for “keys”, it was actually this line:

    let names cs =
      Jv.to_jstr_list @@ Jv.call (Jv.get Jv.global "Object") "keys" [| cs |]

that suggested the solution

If I read between the lines, it appears you are getting frustrated that I’m trying to use the library without reading the Manual/Cookbook cover to cover. However, with most libraries, I feel it should be possible to use them just by searching for type signatures (which I’m struggling quite a bit with Brr on).

Sigh. Of course I am. That’s the usual thing, people complain when there’s no docs and when you provide them with some they don’t want to read them. That doesn’t mean you have to read them cover to cover but at least look into them for answers. A lot of the questions you ask could be answered by yourself if you had.

Asking on this forum may be quicker for you but remember that not everyone is interested in brr and js_of_ocaml here so make sure you are making a good use the finite human attention, patience and ressources provided by the members of this forum.

Right, types are the only documentation you need, could you please explain that to all the people that complain that the OCaml eco-system is not well documented.

Seriously. At a certain point if you want to become productive with the tools you are using you are better off reading the manual and getting an understanding of what you are dealing with.

The reality is that if you want to use js_of_ocaml and brr there will always be parts that are incomplete, not covered or that will never be covered (see the last paragraph at the end of docs here), so you should be ready to do some of binding work yourself if you don’t see it covered by Brr’s APIs (and possibly suggest to add it to Brr if it’s a glaring omission).

This means that you should have a minimal amount of understanding of JavaScript and the FFI exposed by Brr (also in case you run into bugs) which you are lucky enough that I took the time to explain in details along with off the shelf patterns to use in the manual.

In this particular case seeing that Brr doesn’t seem to provide that functionality, searching the web on how to get the properties of a JavaScript object would have landed you on this stackoverflow answer and equipped with the FFI knowledge see that it’s trivial to bind to this method to get what you want.

4 Likes
  1. I’m really grateful for your work on Brr, so I mean all of the following in the most constructive manner.

  2. I believe the greatest hindrance to a more widespread adoption of OCaml / Jsoo / Brr is NOT people like me – who ask “too many” questions; I believe the problem is that people often can not make sense of the docs, give up, and use something else.

  3. The front page of The OCaml Community linking to this forum states:

Ask and answer questions, share and discuss OCaml-related articles and posts, let people know about your projects and find collaborators.

I’m not forcing anyone to answer my questions. There is preferences → users → ignore.

  1. I do not know how “learning” works for you; but for me “read manual → know how to use library” has almost never worked; it’s generally been an iterative process of “try to build something; run into problem; fix problem; iterate”.

  2. I’m not responsible for arguments I never made. I have no doubt that as the maintainer of Brr, different people have made different (often conflicting and frustrating) demands of you; but I did not make those demands and am not responsible for them.

That said, thanks for building Brr; I think I’m finally starting to get a sense of its quirks and sufficiently familiar with the codebase to know where to look. I’m building a “multi threaded system” with WebWorkers, and having the type safety of OCaml structs + Brr for message passing is really nice.

This is not about not making sense of the docs, it’s about not using them, as you acknowledge yourself in point 4.

If there are problems with the docs report them.

1 Like

I think the confusion here is two different types of reading.

Type 1 reading: Like a math book. We read cover to cover. Understand chapters 1 to (n-1) before reading chapter n.

Type 2 reading: Like encyclopedia / wikipedia. Jump to article, read related articles.

===

With goto-class/struct/enum/def/ref , I’m trying to do type 2 “reading” by jumping around in the Editor / IDE, looking up relevant information.

I absolutely admit that I have NOT done type-1 style “cover to cover” reading of Manual + Cookbook.

I think many (not all) other programmers also try to do type-2 style reading with new libraries – get something minimal running, try to build something new, and only reading the relevant/related articles as they go along.

I don’t think you need to do cover to cover reading of the manual and/or the cookbook, they are structured into largely self-contained and cross-referenced sections. Especially not the cookbook which is rather for quickly looking up/recalling on how to deal with specific topics.

I interpreted

as reading Cover to Cover.

If that was not your intention, I apologize for the confusion.

I’m not here to tell you how to spend your quality time with Brr’s documentation.

It was just obvious that you needed more understanding of the way Brr’s FFI works and that you can easily find that in the docs.

Looking at the docs’s section outlines, it should be quite clear that you don’t need to read them cover to cover.

Regarding:

I don’t think the goal of this forum is to start ignoring each other. I prefer if we are all mindful of the resource it provides.

My aim was certainly not to prevent anyone from asking questions but rather leave us bandwidth for helping less experienced users than you – since you often answer your own questions or delete them that may be a sign that you turn too quickly to the forum when you run into problems.

3 Likes

The FFI manual and cookbooks are not particularly long. I have been evaluating Brr for an upcoming project and just reading them. @zeroexcuses If you have some actionable things that you think would have helped you resolve your question faster, without making a post, let me know. Maybe I can find some time to contribute back to Brr with some of your suggestions.

1 Like
  1. I acknowledge that in my OCaml journey, I have (a) tried plenty of stupid things, (b) asked plenty of stupid questions, and (c) often solved my own problem after posting. IMHO, people fail to achieve mastery not because they look like an idiot in the short run, but because out of fear of looking like an idiot, they never try.

  2. I am not convinced my actions “steals bandwidth” from beginners, since every answer is voluntary and I’m not forcing anyone to answer.

  3. Personally, I don’t get irritated with other people’s msgs since I don’t read every Slack msg, I don’t read every Discord msg, I don’t read every reddit post, I don’t read every post here either. I just don’t read things I’m not interested in.

  4. It is clear to me you are upset. It is not clear to me whether I’ve violated any written forum rules.

For (likely older) people like me who use the forum in mailing list mode every post ends up in a message – that’s why many people still see deleted topics. The point is not about answering or not, the point is about having too much messages to sift through.

It’s difficult to determine if you are not interested in a message without reading it :–) I’m of course interested in people struggling with the libraries I publish, but not all struggles are equally interesting. I still have to read the message to determine that.

Things be clear I am absolutely not upset and I don’t think you violated any written forum rules. I was just trying to suggest another course of action.

(And in general don’t mind “stupid” questions)

1 Like

I’ll barge in with an exterior view point, maybe that’ll help…

I can understand @dbuenzli. Maybe there was a nicer way to say it, but he essentially told you to RTFM before asking for help, let it go :slight_smile:

One thing I do find interesting on this forum is the low volume of highly technical posts. So personally, I think twice about posting a nooby question. Most times, I find the answer on my own after a bit of struggle.

That being said, I understand where you’re coming from @zeroexcuses. Exploring the OCaml landscape does feel harder: I can’t skim over, sometimes quite dense, documentation (if it exists) and develop an intuition of things as easily.

I think we should also add: The Discord (or IRC) server is an option to ask noob questions. By definition of the medium, people there expect a torrent of messages and nobody is expected to sift through all of them.
(But then you don’t get the privilege of having Daniel answer your questions :wink: )

1 Like

I’m currently migrating from Brr to Incr_dom / plain jsoo – so I don’t actually need this myself; I’m mentioning this only as what an “ideal” world might look like.

I think it would be really helpful is if all the examples from mdn (ex: Window: postMessage() method - Web APIs | MDN ) were translated to Brr.

This would eliminate the two types of questions at heart of all my questions:

  1. I have this JS expr / statement. How do I translate it to Brr ? Solution: look up function name in mdn-brr-examples, copy/paste, make types match up.

  2. What is an example of how to use JS function foo: Lookup example in mdn-brr-examples.

==

The way this would resolve many questions is that I often do “dune -w” driven development; so I get into a situation where:

  1. I constructed type A
  2. compiler wants type B
  3. I have no idea how to build a B

With mdn-brr-examples, I can easily copy/paste code that build a B-ish, which can then be modified into building a B.