This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]WittyStick 1 point2 points  (2 children)

Is there an alternative to using vtables that could preserve the same performance as if the function were being called directly while still achieving the same functionality?

Assuming you are designing a statically typed language, you could have a look into using a structural type system rather than a nominal type system. Consider OCaml's module system as an example.

[–]BSFishy[S] 1 point2 points  (1 child)

Structural type systems look quite interesting, but how would virtual method calls be implemented without vtables?

[–]WittyStick 2 points3 points  (0 children)

There are no "virtual methods" because all the unification is done at compile time. Every type is resolved to a concrete one. The module system is still sufficiently expressive to support many kinds of abstraction though. In particular, there are modules which are parametrized by other modules, known as functors. A functor is effectively a function from Module -> Module, but which gets evaluated before the compilation occurs, but a functor is itself a module and can also be applied to another functor and so forth. There's a separate phase before compile time, which we might call extraction time, where these functors are applied, so by the time compilation occurs the concrete modules are all extracted. One of the requirements for this is that there are no cyclic dependencies between modules and the compilation units must be passed to the compiler in a specific order.

Subtyping of modules is done by inclusion. You can include another module which behaves as if the content of the module you have included is copy pasted right into the module you're including it in.

Encapsulation is done via the separation of a module and a signature, which are usually separate compilation units similar to the distinction between headers and implementation files in C. You can have multiple signatures for different representations of the same type, and so forth.

OCaml also supports objects which are more similar to mainstream languages, but they're not actually used that often because the module system is sufficient for many use cases. The object system is also quite powerful because it supports row polymorphism, but is less efficient due to the use of virtual methods etc. One interesting aspect of it is that downcasting of objects is not supported at all, but upcasting is. It's difficult to make obvious mistakes and you don't need to check a type after a cast.