Best way to represent a Lua type that both has "static" functions and "instance" functions?
Closed this issue · 4 comments
I think a simplest useful example might be Vector2 from Core. How should this look as a binding in Amulet?
I'm writing this on mobile, so please forgive the inevitable formatting mistakes. I guess I'd do something like:
type t
external val zero : t = "Vector2.ZERO"
external val lerp : t -> t -> float -> t = "Vector2.Lerp"
external val normalise : t -> t = "function(x) return x:GetNormalized()"
The optimiser/backend should be smart enough to inline the last one. Hopefully.
Ah, this makes sense. What'd be a good way to go about "namespacing" this stuff in amulet? I'm assuming amulet wouldn't support something like
type vector2
external val vector2.zero : vector2 = "Vector2.ZERO"
?
Also, how do I get the x
, y
, size
, sizeSquared
values of the Vector?
I'd typically do something like this:
module Vector2 = struct
type t
external val zero : t = "Vector2.ZERO"
end
Then one just writes Vector2.zero
. Alternatively you can split it into separate files, and then just do module Vector = import "./vector2.ml
".
As far as getting fields goes, it's probably safer to write the accessors as functions (rather than declaring the field as a record). So something like:
external val x : t -> float = "function(v) return v.x end"
How do I handle operators?
module Vector2 = struct
type t
external val zero : t = "Vector2.ZERO"
external val one : t = "Vector2.ONE"
external val new : float -> float -> t = "Vector2.New"
external val new : float -> t = "Vector2.New"
external val new : t -> t = "Vector2.New"
external val lerp : t -> t -> float -> t = "Vector2.Lerp"
external val get_normalized : t -> t = "Vector2.GetNormalized"
external val ( + ) : t -> t -> t = "function(a, b) return a + b end"
external val ( + ) : t -> float -> t = "function(a, b) return a + b end"
external val ( - ) : t -> t -> t = "function(a, b) return a - b end"
external val ( - ) : t -> float -> t = "function(a, b) return a - b end"
external val ( * ) : t -> t -> t = "function(a, b) return a * b end"
external val ( * ) : t -> float -> t = "function(a, b) return a * b end"
external val ( * ) : float -> t -> t = "function(a, b) return a * b end"
external val ( / ) : t -> t -> t = "function(a, b) return a / b end"
external val ( / ) : t -> float -> t = "function(a, b) return a / b end"
external val negate : t -> t = "function(a) return -a end"
external val ( *. ) : t -> t -> float = "function(a, b) return a .. b end"
external val ( *+ ) : t -> t -> float = "function(a, b) return a ^ b end"
As of current I can't represent these as infix operators, but I don't know how to handle them otherwise.
( * )
is of special concern: Vector2.( * )
only matches the last definition and not the other two.