1

Bucklescript allows one to define raw js function calls, but it's not clear to me how the return type should be handled. It seems one can use any type and it'll still work. For example, this code compiles and runs without problems:

let f = [%raw {|
  function() {
    return 4;
  }
|}]

let x : (string option) list = f ()

The compiler won't complain that x has type (string option) list or any other bogus type. Normally, I'd just rely on type inference, but I want to assign the result of a raw js function call to a field in a struct, so I do have to define a type for that field in the struct type definition. It seems I can also use whatever type and it'll still work. Is that the expected behavior? Are there any recommendations to deal with these cases?

glennsl
  • 28,186
  • 12
  • 57
  • 75
yewang
  • 585
  • 7
  • 14

1 Answers1

2

Yes, that is expected behavior. The compiler does not try to understand the contents of raw blocks, which makes them quite dangerous to use in general. If there's a syntax error, the compiler will not complain.

The type inference algorithm will always try to infer the most general type, which without any hints otherwise will be... anything. It doesn't even assume it's a function, since it doesn't have to be.

%raw is an expression that can annotated with a type just like any other expression. The magic happens inside it, not outside. You can either give the expression a type directly:

let f = ([%raw {|
  function() {
    return 4;
  }
|}] : unit -> int)

or on the binding, like you do with x:

let f : unit -> int = [%raw {|
  function() {
    return 4;
  }
|}]
glennsl
  • 28,186
  • 12
  • 57
  • 75