# How to create a hashtbl using Base?

**URL:** <https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922>\
**Category:** Learning\
**Tags:** core\
**Created:** [October 5, 2017, 12:39am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922 "2017-10-05T00:39:10Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dudelson](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dudelson/32/167_2.png) [@dudelson](https://discuss.ocaml.org/u/dudelson)\
**Post date:** [October 5, 2017, 12:39am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/1 "2017-10-05T00:39:11Z")

</div>

I cannot for the life of me figure out how to create and use a hashtbl using the Base library. There are some resources online concerning the standard library hashtbls, but I am not sure if the Base hashtbls are supposed to work the same way because the [docs](https://ocaml.janestreet.com/ocaml-core/v0.9/doc/base/Base/Hashtbl/Creators/index.html#type-create_options) don’t seem to concretely define the type provided as an argument to the `create` function (or I could be using the docs wrong because I’m a beginner). I have also tried to follow Ch. 13 of RWO, and did this:

```auto
Hashtbl.create ~hashable:String.hash ()

```

But I get the error:

```auto
Error: The function applied to this argument has type
         ?growth_allowed:bool ->
         ?size:int -> unit -> ('a, 'b) Base__Hashtbl.t
This argument cannot be applied with label ~hashable

```

Again, because I don’t know what the type of the arguments are, I don’t even know if Base still uses the `~hashable` optional argument. Has the interface changed?

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [October 5, 2017, 12:57am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/2 "2017-10-05T00:57:56Z")

</div>

This is one of the few differences between the Base API and that of Core and Core\_kernel. The idiom of Base is as follows:

```ocaml
>>> let table = Hashtbl.create (module Int) ();;
val table : (Base.int, '_a) Hashtbl.t = <abstr>

```

You pass in the first-class module, rather than a specific hashable value within the module in question.

We expect to update RWO to use Base instead of Core and Core\_kernel, but we’re not quite there yet.

y

---

<div class="post-metadata">

**Author:** ![jjb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jjb/32/2713_2.png) [@jjb](https://discuss.ocaml.org/u/jjb)\
**Post date:** [October 5, 2017, 1:24am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/3 "2017-10-05T01:24:44Z")

</div>

A related question while on the topic of the Base vs Core API. Perhaps I’m old-fashioned, but its not uncommon for me to want to use the Base collections as if they had a functorial interface. For example:

```auto
module Order_by_start = struct
  type t = Location.t
  include Comparator.Make (struct
      type t = Location.t
      let sexp_of_t _ = Sexp.Atom "_"
      let compare (x: t) (y: t) = compare_position x.loc_start y.loc_start
    end)
end

module Order_by_end = struct
  type t = Location.t
  include Comparator.Make (struct
      type t = Location.t
      let sexp_of_t _ = Sexp.Atom "_"
      let compare (x: t) (y: t) = compare_position x.loc_end y.loc_end
    end)
end

type start_map = (string * Location.t) list Map.M(Order_by_start).t

type end_map = (string * Location.t) list Map.M(Order_by_end).t

type t = start_map * end_map

let empty_start = Map.empty (module Order_by_start)
let empty_end = Map.empty (module Order_by_end)

let empty : t = (empty_start, empty_end)

```

Is there a slicker way to do this? Note that I want to name the types of the instantiated maps for other uses elsewhere.

I’m bothered by the duplication of the definition of `type t` 4 times. Normally, like when it’s an alias, this is not too bad, but still bothersome. It is also odd to have to pass each Order\_by\_ module to both Map.M and to Map.empty.

Cheers, Josh

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [October 5, 2017, 1:55am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/4 "2017-10-05T01:55:03Z")

</div>

Well, you can do something like:

```ocaml
module Order_by_start = struct
  include Location 
  include Comparator.Make (struct
      include Location
      let compare (x: t) (y: t) = compare_position x.loc_start y.loc_start
  end)
end

```

which is a little shorter, and I think should work.

y

---

<div class="post-metadata">

**Author:** ![dudelson](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dudelson/32/167_2.png) [@dudelson](https://discuss.ocaml.org/u/dudelson)\
**Post date:** [October 5, 2017, 3:28pm UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/5 "2017-10-05T15:28:38Z")

</div>

Thanks for the quick reply 😀 This answer is enough to get me up and running with Base Hashtbls for the time being, but in general I’d also like to take this opportunity to get better at reading Ocaml docs. I’m wondering if a seasoned ocaml veteran would have been able to figure this out themselves just by reading the Base.Hashtbl documentation, and if so, how they would go about it.

Concretely, I found the `create` function by starting from Base.Hashtbl \> Creators and expanding the included Hashtbl\_intf.Creators. But the function has type `('a key, 'b, unit ‑> ('a, 'b) t) create_options`, which appears to be a hidden type, so I got stuck. I noticed that in the included module, `create_options` was constrained to `Hashtbl_intf.create_options_without_hashable`, so I clicked on that, but it was equally unhelpful. What am I missing?

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [October 6, 2017, 2:19am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/6 "2017-10-06T02:19:31Z")

</div>

Yeah, navigating through the types can be painful. There’s work on making odoc do a better job of peering through the aliases to see the underlying type. Merlin can already do this. In emacs, anyway, if you ask for the type twice, the second time it looks through all the type aliases. So the first time you get this:

```ocaml
('a, 'b, unit -> ('a, 'b) Hashtbl.t)
Hashtbl_intf.create_options_with_first_class_module

```

and the second time you get this:

```ocaml
(module Hashtbl_intf.Key_plain with type t = 'a) ->
?growth_allowed:bool -> ?size:int -> unit -> ('a0, 'b) Hashtbl.t

```

---

<div class="post-metadata">

**Author:** ![dudelson](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dudelson/32/167_2.png) [@dudelson](https://discuss.ocaml.org/u/dudelson)\
**Post date:** [October 6, 2017, 2:17pm UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/7 "2017-10-06T14:17:11Z")

</div>

That’s pretty cool! Never knew merlin could do that. So it seems like it expects a module of type `Hashtbl_intf.Key_plain`. But then how do I know that this means I’m allowed to pass in `String`? I looked at the `String` docs again and I don’t see any references to `Key_plain` there.

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [October 6, 2017, 8:50pm UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/8 "2017-10-06T20:50:39Z")

</div>

There’s nothing explicit in String that tells you this. You’d have to go and look at Key\_plain and see what it requires. For example, if you look at the latest release of Base, you’ll see this signature:

```ocaml
module type Key = sig
  type t [@@deriving compare, sexp_of]

  (** Values returned by [hash] must be non-negative. An exception will be raised in the
      case that [hash] returns a negative value. *)
  val hash : t -> int
end

```

This means that any module that has a compare function, a sexp\_of function, and a hash function should match this signature, and could be passed in as an argument.

---

<div class="post-metadata">

**Author:** ![BikalGurung](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bikalgurung/32/5105_2.png) [@BikalGurung](https://discuss.ocaml.org/u/BikalGurung)\
**Post date:** [October 19, 2017, 11:08am UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/9 "2017-10-19T11:08:25Z")

</div>

Another possible issue: the hash table in base and core/core\_kernel doesn’t seem to be compatible. I came across this issue when the project that was using the base hash table wouldn’t compile when the package was moved to core/core\_kernel. I think core/core\_kernel requires hashable interface to be implemented whereas in base this is not required.

Additionally, I find the base/core\_kernel api not consistent. It seems sometimes you can/must use functor while sometimes you have to use first class modules to use these modules. Maybe if the document was there this wouldn’t be much of an issue. However, since the documention is quite sparse this inconsistency is quite frustrating and time-consuming.

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [October 21, 2017, 6:45pm UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/10 "2017-10-21T18:45:21Z")

</div>

To be clear, the types are compatible, but the APIs for constructing tables and maps do differ. This is something we’re looking to fix, by adjusting the Core/Core\_kernel APIs to match Base.

---

<div class="post-metadata">

**Author:** ![BikalGurung](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bikalgurung/32/5105_2.png) [@BikalGurung](https://discuss.ocaml.org/u/BikalGurung)\
**Post date:** [October 24, 2017, 10:40pm UTC](https://discuss.ocaml.org/t/how-to-create-a-hashtbl-using-base/922/11 "2017-10-24T22:40:39Z")

</div>

Thanks for the update. Looking forward to the next update.
