int3
int3

Reputation: 13201

Can I inherit from an OCaml class chosen at runtime?

So right now I have two classes of the same class type, e.g.

class foo : foo_type = object ... end

class bar : foo_type = object ... end

I'd like to have a third class that inherits from either foo or bar at runtime. E.g. (pseudo-syntax)

class baz (some_parent_class : foo_type) = object
    inherit some_parent_class
    ...
end

Is this possible in OCaml?

Use case: I'm using objects for constructing AST visitors, and I'd like to be able to combine these visitors based on a set of runtime criteria so that they only do one combined traversal over the AST.

Edit: I think I have found a way to create the desired class using first-class modules:

class type visitor_type = object end

module type VMod = sig
  class visitor : visitor_type
end

let mk_visitor m =
  let module M = (val m : VMod) in
  (module struct
    class visitor = object
      inherit M.visitor
    end
  end : VMod)

However, it seems a little roundabout to have to wrap a class in a module in order to make it "first-class". If there's a more straightforward way please let me know.

Upvotes: 5

Views: 160

Answers (3)

Leo White
Leo White

Reputation: 1151

This is just a cleaner implementation of what you already suggested, but I would do it like this:

module type Foo = sig
  class c : object
    method x : int
  end
end

module A = struct
  class c = object method x = 4 end
end

module B = struct
  class c = object method x = 5 end
end

let condition = true

module M = (val if condition then (module A) else (module B) : Foo)

class d = object (self)
  inherit M.c
  method y = self#x + 2
end

Upvotes: 5

ivg
ivg

Reputation: 35260

Not contrary to what Jeffrey said, but you can achieve this using first-class modules. Also, I'm not sure that you really need to create classes on runtime, maybe creating object would be enough. If what you want to get is different behavior, then this will be enough.

Upvotes: 3

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66813

OCaml has a static type system. You can't do anything at runtime that would affect the type of something. Inheritance affects the types of things, so it can't happen at runtime.

(Your code also confuses types with values, which is understandable.)

There is probably a way to get close to what you want while retaining the desirable properties of static typing. What you actually need may be more like function composition, perhaps.

Upvotes: 2

Related Questions