# Is it possible to return a polymorphic function using Obj.magic?

**URL:** <https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832>\
**Category:** Learning\
**Created:** [April 10, 2018, 5:16am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832 "2018-04-10T05:16:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobzhang](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobzhang/32/553_2.png) [@bobzhang](https://discuss.ocaml.org/u/bobzhang)\
**Post date:** [April 10, 2018, 5:16am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/1 "2018-04-10T05:16:52Z")

</div>

It seems Obj.magic is not magical enough, I want to cast an expression to a polymorphic function type, below is a simple example:

```ocaml
let f : 'a -> unit = Obj.magic 3

```

In the end, it will complain that it contains variables that can not be generalized, I kinda know why it works this way, my question is that if there is a way to coerce an expression to an arbitrary type

```ocaml
let f = (coerce exp: 'a -> int ) (* or any type you want *)

```

---

<div class="post-metadata">

**Author:** ![objmagic](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/objmagic/32/9_2.png) [@objmagic](https://discuss.ocaml.org/u/objmagic)\
**Post date:** [April 10, 2018, 5:46am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/2 "2018-04-10T05:46:01Z")

</div>

Does this work?

```auto
type poly = {f: 'a. 'a -> int};;
  
let w = {f = Obj.magic 3};;

w.f

```

---

<div class="post-metadata">

**Author:** ![bobzhang](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobzhang/32/553_2.png) [@bobzhang](https://discuss.ocaml.org/u/bobzhang)\
**Post date:** [April 10, 2018, 5:53am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/3 "2018-04-10T05:53:52Z")

</div>

This would work for this case. It would be ideal if there is a mechanical way to break type system, the coerced type could be arbitrary function types

---

<div class="post-metadata">

**Author:** ![gsg](https://avatars.discourse-cdn.com/v4/letter/g/858c86/32.png) [@gsg](https://discuss.ocaml.org/u/gsg)\
**Post date:** [April 10, 2018, 11:23am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/4 "2018-04-10T11:23:37Z")

</div>

Isn’t this due to the value restriction rather than some property of `Obj.magic`?

---

<div class="post-metadata">

**Author:** ![Drup](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/drup/32/35_2.png) [@Drup](https://discuss.ocaml.org/u/Drup)\
**Post date:** [April 10, 2018, 11:57am UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/5 "2018-04-10T11:57:56Z")

</div>

Yes, it’s the value restriction. You just need an intermediary step:

```ocaml
# let x = Obj.magic 3 ;;
val x : 'a = <poly>
# let f : 'a -> int = x ;;
val f : 'a -> int = <fun>

```

---

<div class="post-metadata">

**Author:** ![bobzhang](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bobzhang/32/553_2.png) [@bobzhang](https://discuss.ocaml.org/u/bobzhang)\
**Post date:** [April 10, 2018, 12:11pm UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/6 "2018-04-10T12:11:23Z")

</div>

Indeed, for people who are curious about what I want to do, in BuckleScript we want to allow people to insert arbitrary js code to get job done sometimes. Originally:

```ocaml
let forIn : 'a -> (string -> unit) -> unit = 
   fun%raw o foo -> {|
  for (var i in o){
    foo(o)
  }
  |}

```

but the `forIn` is not really polymorphic, here is a temporary work around:

```auto
let forIn = 
   (fun%raw o foo -> {|
  for (var i in o){
    foo(o)
  }
  |})

  let forIn : 'a -> (string -> unit) -> unit = forIn  

```

Let me know if you have some ideas to streamline the workflow, I know it is not cool to use Obj.magic, but it is important to ship than waiting everything to be perfect : )

Edit: it seems such work around only works for toplevel bindings not local bindings (`let .. in`)

---

<div class="post-metadata">

**Author:** ![gsg](https://avatars.discourse-cdn.com/v4/letter/g/858c86/32.png) [@gsg](https://discuss.ocaml.org/u/gsg)\
**Post date:** [April 10, 2018, 12:50pm UTC](https://discuss.ocaml.org/t/is-it-possible-to-return-a-polymorphic-function-using-obj-magic/1832/7 "2018-04-10T12:50:49Z")

</div>

The value restriction works in the same way for top level and local bindings:

```
let f () =
  let g = Obj.magic (fun (x : int) -> ()) in
  let h : 'a. 'a -> unit = g in
  h (), h 1

```

You may be running into an different issue, eg, non-generalisation of type variables from a level higher than the `let`. It’s hard to say without a concrete example…
