jamis / rtc-ocaml

"The Ray Tracer Challenge" (http://www.raytracerchallenge.com) implemented in OCaml
15 stars 3 forks source link

Use module functors for shapes #2

Open citizen428 opened 4 years ago

citizen428 commented 4 years ago

Since I'm implementing the Ray Tracer Challenge in F#, I sometimes come to this repository for inspiration. One thing that always "bothered" me a little bit was the relation between Shape and its implementations, like Sphere. So now that I learned more about OCaml functors, I played around a bit and came up with an alternative implementation. It's obviously simplified (all the functions are dummies) and leaves out some of the related types like Ray, Intersection etc., but it should be enough to get the idea across:

module type ShapeFns = sig
  val intersect : float -> float list
  val normal : float -> float
end

module type Shape = sig
  val intersect : float -> float list
  val normal : float -> float
end

module Make_Shape (M : ShapeFns) : Shape = struct
  let intersect n = M.intersect (n +. 1.)
  let normal n = M.normal n *. 2.
end

module Sphere = Make_Shape (struct
  let intersect n = [ n; n -. 1. ]
  let normal n = n *. 2.
end)

let i = Sphere.intersect 5.
let n = Sphere.normal 2.

Or even:

module type Shape = sig
  val intersect : float -> float list
  val normal : float -> float
end

module Make_Shape (M : Shape) : Shape = struct
  let intersect n = M.intersect (n +. 1.)
  let normal n = M.normal n *. 2.
end

module Sphere = Make_Shape (struct
  let intersect n = [ n; n -. 1. ]
  let normal n = n *. 2.
end)

let i = Sphere.intersect 5.
let n = Sphere.normal 2.

I think this is quite nice and like that it allows us to call functions on the specific module instead of Shape.

Anyway, just wanted to share this approach and didn't know a better way to get in touch 😃

jamis commented 1 year ago

I have no idea why I didn't get a notification for this, but I'm just now seeing it. Thank you so much for sharing this! As I mentioned in the README, this was my first ever project with OCaml, so there was a lot I probably did "the hard way".

This is much more elegant that what I did! If I ever find the time to get back to this, I'll definitely research modules more!

citizen428 commented 1 year ago

I have no idea why I didn't get a notification for this

Haha, oh well, it wasn't exactly urgent. :-)

Thanks for your book btw, it was very enjoyable!