lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Tue, Nov 27, 2018 at 9:49 AM Soni L. <fakedme@gmail.com> wrote:
>
> You lost me, sorry. I'm not sure how python/C++ actually do this, but Cratera, like Rust, lets you do:
>
> foo:bar.baz()
> foo:baz.baz()
>
> Where each do their own thing.
>
> The Rust equivalent is (roughly)
>
> <Foo as Bar>::baz(foo);
> <Foo as Baz>::baz(foo);
>
> (there are variations you can use, such as `Bar::baz(foo)` instead of `<Foo as Bar>::baz(foo)`)

In C++ by default you actually DON'T get the ability to preserve a
pointer to the foo; you only get a pointer to the version that's been
cast to bar. There are techniques that are used to circumvent this
problem such as CRTP, but as I said, doing it with multiple
inheritance is unpopular, and in practice this kind of component-based
architecture gets built more explicitly instead of just using the
language's built-in features.

With Python's builtins, you just use foo.baz(), and then "self" will
be foo. You don't explicitly call out bar. Yes, this DOES cause
problems if two of your components have conflicting names. You just
try to avoid doing that. (The language provides some name mangling for
internal-use-only members to help mitigate the issue.) There are
metaclass shenanigans you can use if you want something fancier.

But the point I was trying to make is that you shouldn't try to think
of this as an inheritance scheme, because what you're talking about
isn't inheritance. It's composition. Composition is done using
inheritance in some languages, but there are other alternatives that
don't involve inheritance. The Cratera technique isn't achieving
composition through inheritance; it's achieving it through lexical
binding, which is a perfectly natural way of doing it in Lua since Lua
uses lexical binding for member functions in the first place.
(Javascript also uses lexical binding. Python... sort of does.)

/s/ Adam