# Module quasi-object syntax

**URL:** <https://discuss.ocaml.org/t/module-quasi-object-syntax/5923>\
**Category:** Learning\
**Created:** [June 6, 2020, 12:07am UTC](https://discuss.ocaml.org/t/module-quasi-object-syntax/5923 "2020-06-06T00:07:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![donn](https://avatars.discourse-cdn.com/v4/letter/d/7ea924/32.png) [@donn](https://discuss.ocaml.org/u/donn)\
**Post date:** [June 6, 2020, 12:07am UTC](https://discuss.ocaml.org/t/module-quasi-object-syntax/5923/1 "2020-06-06T00:07:09Z")

</div>

I have been fooling around with what I believe are “first class” modules, and have a syntax problem - there is no way, am I right?

From here  
type x = { a: (module Gesture) }

```
let v = { a = create_wave "hi" }

```

I can do this:  
`in let (module G: Gesture) = v.a in G.perform ()`

… but no way to apply directly to the record field, without a “let binding”?  
`in v.a.perform ()`

(rest of code for example follows:)

```
module type Gesture = sig
    type t
    val gesture : t
    val perform : unit -> unit
    end

let create_wave s =
    let module Wave: Gesture = struct
        type t = string
        let gesture = s
        let perform () = Printf.printf "Wave \"%s\"\n" gesture
        end
    in (module Wave : Gesture)

let create_finger i =
    let module Finger: Gesture = struct
        type t = int
        let gesture = i
        let perform () = Printf.printf "Finger %d\n" gesture
        end
    in (module Finger: Gesture)
```

---

<div class="post-metadata">

**Author:** ![ale](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ale/32/1540_2.png) [@ale](https://discuss.ocaml.org/u/ale)\
**Post date:** [June 7, 2020, 5:32pm UTC](https://discuss.ocaml.org/t/module-quasi-object-syntax/5923/2 "2020-06-07T17:32:16Z")

</div>

If I understand correctly, no, you can’t just “apply directly to the record field”. I guess the reason for this is that type inference is often driven by syntax and in the case of `v.a.perform` it is understood that `v.a` should have record type (in the same way that `v` should have record type previously in `v.a`) since module names are capitalized.

If you are annoyed by writing the type explicitly in the let binding, you can also write:

```auto
  let v = { a = create_wave "hi" } in
  let module G = (val v.a) in
  G.perform ()

```

Hope it helps!

Disclaimer: I’m a beginner in the language, so take this with a grain of salt.
