Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I inherit from an OCaml class chosen at runtime?

Tags:

ocaml

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.

like image 605
int3 Avatar asked Feb 19 '15 17:02

int3


People also ask

Is there inheritance in OCaml?

Private methods are inherited (they are by default visible in subclasses), unless they are hidden by signature matching, as described below. Private methods can be made public in a subclass.

Does OCaml have classes?

OCaml Classes Like module types, class types are completely separate from regular OCaml types (e.g., int , string , and list ) and, in particular, should not be confused with object types (e.g., < get : int; .. > ). The class type describes the class itself rather than the objects that the class creates.

Does OCaml have objects?

Objects and classes. OCaml is an object-oriented, imperative, functional programming language :-) It mixes all these paradigms and lets you use the most appropriate (or most familiar) programming paradigm for the task at hand.


2 Answers

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
like image 180
Leo White Avatar answered Oct 10 '22 13:10

Leo White


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.

like image 29
ivg Avatar answered Oct 10 '22 14:10

ivg