Lua Needs

classic Classic list List threaded Threaded
43 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Lua Needs

Soni L.
I would like to use Lua again, but it falls short on some of my needs:

- The GC is not reentrant, as such it cannot do garbage collection or
call debug hooks inside __gc hooks. This is a dealbreaker, as it has
serious consequences for sandboxing.
- Lua has little to no support for composition-based OOP, whereas it has
many features to support inheritance (__index/__newindex) and other
forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
easily solved with a rather small patch.

These would be nice to have.

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Pierre Chapuis
On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:

> - Lua has little to no support for composition-based OOP, whereas it has
> many features to support inheritance (__index/__newindex) and other
> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
> easily solved with a rather small patch.

Can you give an example of what you would want here?

Because for me, "composition-based OOP" does not need much
language support. For what it's worth I almost never use inheritance
in Lua (or any other language, really).

--
Pierre Chapuis

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Soni L.


On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:

> On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>
>> - Lua has little to no support for composition-based OOP, whereas it has
>> many features to support inheritance (__index/__newindex) and other
>> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> easily solved with a rather small patch.
> Can you give an example of what you would want here?
>
> Because for me, "composition-based OOP" does not need much
> language support. For what it's worth I almost never use inheritance
> in Lua (or any other language, really).
>

The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

[1] https://bitbucket.org/TeamSoni/cratera

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Philippe Verdy


Le lun. 26 nov. 2018 à 11:30, Soni "They/Them" L. <[hidden email]> a écrit :
The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.
[1] https://bitbucket.org/TeamSoni/cratera

Write it in Lua as
  foo[component].method(foo), or
  foo[component]['method'](foo)

I don't see what the "cratera" fork brings which is not already part of standard Lua...
You can still use an expression to replace any identifier, just replace the " .identifier " syntax by " ['identifier'] ".
The colon is just a syntaxic sugar in Lua for passing an object (a table) in the first parameter of a function which is one of the property values of the object). And there's not even any need to change the VM to support it, you can always rewrite the expression with colon into a function call.

The interest of the colon however is that this common expression (for computing the reference of the object) is coimputed only once and duplicated (kept in an hidden temporary variable or register) before first dereferencing it to extract one of its property (which is a function) and then reuse it as the first parameter to call the function.
It only exists because Lua does not "directly" allow using assignments in the middle of an an expression.

But there's a way to perform an assignment in a local variable in the middle of an expression in standard Lua. For example the following is not allowed by the syntax:

  y = (local x; sin(x = arbitrary_expression()) + cos(x))

But you can rewrite it using a local function in a closure to perform the assignment by calling that function:

  local x;
  y  = sin( (function(){x =  arbitrary_expression()})() ) + cos(x)

or more equivalently (to limit the scope of "x" inside the expression) as:

  y  = (function() {local x; return sin( (function(){x =  arbitrary_expression()})() ) + cos(x)})()

Here also you don't need any change to Lua or its interpreter or compiler, or to the VM. The possibility of performing asignments in the middle of expressions, and even adding local varaible declaration would just make it more easier (temporary variables are frequently needed to store the results of common subexpressions that you MUST NOT evaluate multiple times without introiducing side-effects, notably if the "common subexpression contains function calls, for example performing some I/O or modifying other referenced objects or other objects hiden in the function closure).

Having the possibility of directly declaring local variables in the middle of expresssions would be useful and productive (and it would perform various optimizations that are hard to realize in interpreters and compilers, that have to perform complex matching search to detect common subexpressions and check if their semantics is really equivalent).

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Egor Skriptunoff-2
In reply to this post by Soni L.
On Mon, Nov 26, 2018 at 1:30 PM Soni "They/Them" L. wrote:
>> - Lua has little to no support for composition-based OOP
> Can you give an example of what you would want here?
The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

What OOP languages do support this "composition-based OOP" ?
Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Coda Highland
On Mon, Nov 26, 2018 at 6:58 AM Egor Skriptunoff
<[hidden email]> wrote:

>
> On Mon, Nov 26, 2018 at 1:30 PM Soni "They/Them" L. wrote:
>>
>> >> - Lua has little to no support for composition-based OOP
>>
>> > Can you give an example of what you would want here?
>> The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.
>
>
> What OOP languages do support this "composition-based OOP" ?

Lots of them. C++, Java, C#, Python... Javascript doesn't usually do
it that way but its ability to do dynamic function rebinding would
make it POSSIBLE to do it there (I just don't know anyone that
bothers).

The syntax isn't usually that pretty, though. Python's the only one I
know of off the top of my head that can make it look that clean. In C#
it looks more like foo.GetComponent<Component>().Method().

Lua actually can pull it off with foo[component]:method() if you have
foo's __index metamethod return a binding object, but that comes at
the cost of a fair amount of overhead relative to the syntax patch.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Russell Haley
In reply to this post by Soni L.


On Mon, Nov 26, 2018 at 2:30 AM Soni "They/Them" L. <[hidden email]> wrote:


On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:
> On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>
>> - Lua has little to no support for composition-based OOP, whereas it has
>> many features to support inheritance (__index/__newindex) and other
>> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> easily solved with a rather small patch.
> Can you give an example of what you would want here?
>
> Because for me, "composition-based OOP" does not need much
> language support. For what it's worth I almost never use inheritance
> in Lua (or any other language, really).
>

The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

[1] https://bitbucket.org/TeamSoni/cratera

I looked at cratera once but didn't grasp the benefits because I don't write games. Months later I was reading Roblox game code and the use case for cratera became crystal clear. Likewise, Garry's Mod has very deep component nesting and a library like cratera would simplify development.[1]

[1] I still don't write games so I may be off mark.

Russ
Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Gabriel Bertilson
I haven't done game programming in Lua, but it occurred to me that the
component syntax would allow you to use utf8 functions as string
methods: ('βλαβλα'):utf8.codepoint(1, -1) instead of
utf8.codepoint('βλαβλα', 1, -1). That's neat. The utf8 library would
have to be added as a field inside the __index metafield of the string
metatable.

— Gabriel
On Mon, Nov 26, 2018 at 6:02 PM Russell Haley <[hidden email]> wrote:

>
>
>
> On Mon, Nov 26, 2018 at 2:30 AM Soni "They/Them" L. <[hidden email]> wrote:
>>
>>
>>
>> On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:
>> > On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>> >
>> >> - Lua has little to no support for composition-based OOP, whereas it has
>> >> many features to support inheritance (__index/__newindex) and other
>> >> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> >> easily solved with a rather small patch.
>> > Can you give an example of what you would want here?
>> >
>> > Because for me, "composition-based OOP" does not need much
>> > language support. For what it's worth I almost never use inheritance
>> > in Lua (or any other language, really).
>> >
>>
>> The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.
>>
>> [1] https://bitbucket.org/TeamSoni/cratera
>>
> I looked at cratera once but didn't grasp the benefits because I don't write games. Months later I was reading Roblox game code and the use case for cratera became crystal clear. Likewise, Garry's Mod has very deep component nesting and a library like cratera would simplify development.[1]
>
> [1] I still don't write games so I may be off mark.
>
> Russ

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Magicks M
In reply to this post by Soni L.
foo.component.method(foo, ...) is support for this style of programming. If you really want it to look better you could wrap the methods in a function.
Simple example to illustrate my idea:

function redirect(method)
    return function(component, ...) return method(component.object, ...) end
end
-- declare this helper to register component actions
-- one could also just wrap the method directly i.e `redirect(function(object`
function component:action(name)
   self[name] = redirect(self[name])
end

function component:something()
   -- code here self == the object
end
component:action 'something' --register it as an action on the object the component is attatched to.
-- `foo.component:something()` will now work assuming components are wired up to have that .object reference.

While this example is clearly not complete, I hope it illustrates the suggestion clearly enough. I actually prefer the verbose method though, since a big part of composition based designs is being able to decouple the actions and the data (example is using an ECS) so having that clear reference too foo makes sense to me.

   


On Mon, Nov 26, 2018 at 10:30 AM Soni "They/Them" L. <[hidden email]> wrote:


On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:
> On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>
>> - Lua has little to no support for composition-based OOP, whereas it has
>> many features to support inheritance (__index/__newindex) and other
>> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> easily solved with a rather small patch.
> Can you give an example of what you would want here?
>
> Because for me, "composition-based OOP" does not need much
> language support. For what it's worth I almost never use inheritance
> in Lua (or any other language, really).
>

The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

[1] https://bitbucket.org/TeamSoni/cratera

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Sam Pagenkopf
In reply to this post by Russell Haley
object.component.method(object) => object:component.method()
^ I also tried this syntax (and was sad it didn't work), but it's not so bad. That strategy makes for cross-cutting communication between components, which is not the greatest thing. It also assumes that call your parents, but not your grandparents! Here's my alternative, a "parent" variable:

Within calls, replace:
object.component.method(object) => object.component:method()

And within component methods:
self => self.parent
self.<<name of this component>> => self

Then, just add a parent member to constructors.

This also makes it easier to do the better thing; preferring self.x over self.parent.x, which avoids conflict and does some "light" encapsulation. If you do cross-cutting communication within the parent, rather than between components, that's also better, and you might not even need a parent variable at all.

Let me know if that's helpful.

On Mon, Nov 26, 2018 at 6:01 PM Russell Haley <[hidden email]> wrote:


On Mon, Nov 26, 2018 at 2:30 AM Soni "They/Them" L. <[hidden email]> wrote:


On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:
> On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>
>> - Lua has little to no support for composition-based OOP, whereas it has
>> many features to support inheritance (__index/__newindex) and other
>> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> easily solved with a rather small patch.
> Can you give an example of what you would want here?
>
> Because for me, "composition-based OOP" does not need much
> language support. For what it's worth I almost never use inheritance
> in Lua (or any other language, really).
>

The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

[1] https://bitbucket.org/TeamSoni/cratera

I looked at cratera once but didn't grasp the benefits because I don't write games. Months later I was reading Roblox game code and the use case for cratera became crystal clear. Likewise, Garry's Mod has very deep component nesting and a library like cratera would simplify development.[1]

[1] I still don't write games so I may be off mark.

Russ
Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

云风 Cloud Wu
Sam Pagenkopf <[hidden email]> 于2018年11月27日周二 上午9:26写道:
>
> object.component.method(object) => object:component.method()
> ^ I also tried this syntax (and was sad it didn't work), but it's not so bad. That strategy makes for cross-cutting communication between components, which is not the greatest thing. It also assumes that call your parents, but not your grandparents! Here's my alternative, a "parent" variable:

My alternative is when we add a component to an object, I copy all the
methods of component into object's meta table, and we can use it in
this way :

object:component_method(...) => object.component.method(object, ...)


--
http://blog.codingnow.com

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Soni L.
In reply to this post by Sam Pagenkopf
Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.

Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.

On Mon, Nov 26, 2018, 23:26 Sam Pagenkopf <[hidden email] wrote:
object.component.method(object) => object:component.method()
^ I also tried this syntax (and was sad it didn't work), but it's not so bad. That strategy makes for cross-cutting communication between components, which is not the greatest thing. It also assumes that call your parents, but not your grandparents! Here's my alternative, a "parent" variable:

Within calls, replace:
object.component.method(object) => object.component:method()

And within component methods:
self => self.parent
self.<<name of this component>> => self

Then, just add a parent member to constructors.

This also makes it easier to do the better thing; preferring self.x over self.parent.x, which avoids conflict and does some "light" encapsulation. If you do cross-cutting communication within the parent, rather than between components, that's also better, and you might not even need a parent variable at all.

Let me know if that's helpful.

On Mon, Nov 26, 2018 at 6:01 PM Russell Haley <[hidden email]> wrote:


On Mon, Nov 26, 2018 at 2:30 AM Soni "They/Them" L. <[hidden email]> wrote:


On 2018-11-26 7:22 a.m., Pierre Chapuis wrote:
> On Mon, Nov 26, 2018, at 01:15, Soni They/Them L. wrote:
>
>> - Lua has little to no support for composition-based OOP, whereas it has
>> many features to support inheritance (__index/__newindex) and other
>> forms of OOP (self:methods()). This isn't a big deal, tho, as it can be
>> easily solved with a rather small patch.
> Can you give an example of what you would want here?
>
> Because for me, "composition-based OOP" does not need much
> language support. For what it's worth I almost never use inheritance
> in Lua (or any other language, really).
>

The classic Cratera[1] `foo:[component].method()` (note the colon) syntax.

[1] https://bitbucket.org/TeamSoni/cratera

I looked at cratera once but didn't grasp the benefits because I don't write games. Months later I was reading Roblox game code and the use case for cratera became crystal clear. Likewise, Garry's Mod has very deep component nesting and a library like cratera would simplify development.[1]

[1] I still don't write games so I may be off mark.

Russ
Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Coda Highland
On Mon, Nov 26, 2018 at 8:51 PM Soni L. <[hidden email]> wrote:
>
> Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.
>
> Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.

So on the one hand, you're completely right. Traits are a much better
model for this than inheritance, and mixing traits and inheritance can
indeed get quite messy.

But on the other hand, that still leaves the matter of "what's the
best way to implement traits in Lua?" as a question to be discussed.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Sam Pagenkopf
I'd imagine that a trait system in lua would have a set of trait tests that run before the program, and attach methods. Each trait would be a unique table of requirements and possibly default implementations. Each object would have some way of saying it implements said trait, either explicitly or duck-typed. Instead of verifying input and output parameters, the best you could probably do is run tests. It doesn't seem massively useful, but it could be a nice sort of subset of a class framework. If there's interest, I might try to write one.

On Mon, Nov 26, 2018 at 9:55 PM Coda Highland <[hidden email]> wrote:
On Mon, Nov 26, 2018 at 8:51 PM Soni L. <[hidden email]> wrote:
>
> Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.
>
> Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.

So on the one hand, you're completely right. Traits are a much better
model for this than inheritance, and mixing traits and inheritance can
indeed get quite messy.

But on the other hand, that still leaves the matter of "what's the
best way to implement traits in Lua?" as a question to be discussed.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Soni L.
In reply to this post by Coda Highland


On Tue, Nov 27, 2018, 01:55 Coda Highland <[hidden email] wrote:
On Mon, Nov 26, 2018 at 8:51 PM Soni L. <[hidden email]> wrote:
>
> Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.
>
> Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.

So on the one hand, you're completely right. Traits are a much better
model for this than inheritance, and mixing traits and inheritance can
indeed get quite messy.

But on the other hand, that still leaves the matter of "what's the
best way to implement traits in Lua?" as a question to be discussed.

/s/ Adam

Sorry, uh, is it okay if I ask what you mean by that?

I mean, I was specifically saying these shouldn't be a thing:

foo:thing.other.more.why() -> foo.thing.other.more.why(foo)

foo.thing.other.more:why() -> the ability to use self.super.super.super to access foo

Mostly because they look nothing like traits, but also because they look like some weird attempt at inheritance?
Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Coda Highland
On Tue, Nov 27, 2018 at 3:42 AM Soni L. <[hidden email]> wrote:

>
>
>
> On Tue, Nov 27, 2018, 01:55 Coda Highland <[hidden email] wrote:
>>
>> On Mon, Nov 26, 2018 at 8:51 PM Soni L. <[hidden email]> wrote:
>> >
>> > Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.
>> >
>> > Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.
>>
>> So on the one hand, you're completely right. Traits are a much better
>> model for this than inheritance, and mixing traits and inheritance can
>> indeed get quite messy.
>>
>> But on the other hand, that still leaves the matter of "what's the
>> best way to implement traits in Lua?" as a question to be discussed.
>>
>> /s/ Adam
>
>
> Sorry, uh, is it okay if I ask what you mean by that?
>
> I mean, I was specifically saying these shouldn't be a thing:
>
> foo:thing.other.more.why() -> foo.thing.other.more.why(foo)
>
> foo.thing.other.more:why() -> the ability to use self.super.super.super to access foo
>
> Mostly because they look nothing like traits, but also because they look like some weird attempt at inheritance?

First off: This isn't inheritance at all. It's composition. Some
languages do support composition via inheritance (C++, Python), but in
the larger programming world it's not a popular paradigm because of
all of the issues that arise in multiple inheritance.

There's no SPECIFIC reason why foo:bar.baz() -> foo.bar.baz(foo) can't
be supported. I have no complaints about that syntax as long as only a
single : is supported in an expression. It might be a bit ugly to
handle at parse time or at run time, but the fact that Cratera
supports it suggests it's not THAT bad.

self.super.super.super fails HARD, though, because the notion of
"super" there becomes bound up in the specific way the expression is
constructed. Consider this:

local more = foo.thing.other.more
more:why() -- what does self.super mean here?

The "more" object there has no idea that it's contained within
"foo.thing.other" unless you explicitly assign the value of "super" in
the object -- at which point that works just fine in current Lua
without any modifications at all -- or if you do what Python does and
you have . return a binding object instead of the object itself. But
tracking the whole call-time super chain adds an arbitrary amount of
overhead to every function call expression even if it's never going to
be used.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Soni L.
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)`)

On Tue, Nov 27, 2018, 13:22 Coda Highland <[hidden email] wrote:
On Tue, Nov 27, 2018 at 3:42 AM Soni L. <[hidden email]> wrote:
>
>
>
> On Tue, Nov 27, 2018, 01:55 Coda Highland <[hidden email] wrote:
>>
>> On Mon, Nov 26, 2018 at 8:51 PM Soni L. <[hidden email]> wrote:
>> >
>> > Suggestion: Don't assume (or use) inheritance. Or at least don't mix inheritance with components.
>> >
>> > Rust has traits, which are somewhat similar to components, but it doesn't have inheritance. That's because mixing traits/components and inheritance is, at best, messy.
>>
>> So on the one hand, you're completely right. Traits are a much better
>> model for this than inheritance, and mixing traits and inheritance can
>> indeed get quite messy.
>>
>> But on the other hand, that still leaves the matter of "what's the
>> best way to implement traits in Lua?" as a question to be discussed.
>>
>> /s/ Adam
>
>
> Sorry, uh, is it okay if I ask what you mean by that?
>
> I mean, I was specifically saying these shouldn't be a thing:
>
> foo:thing.other.more.why() -> foo.thing.other.more.why(foo)
>
> foo.thing.other.more:why() -> the ability to use self.super.super.super to access foo
>
> Mostly because they look nothing like traits, but also because they look like some weird attempt at inheritance?

First off: This isn't inheritance at all. It's composition. Some
languages do support composition via inheritance (C++, Python), but in
the larger programming world it's not a popular paradigm because of
all of the issues that arise in multiple inheritance.

There's no SPECIFIC reason why foo:bar.baz() -> foo.bar.baz(foo) can't
be supported. I have no complaints about that syntax as long as only a
single : is supported in an expression. It might be a bit ugly to
handle at parse time or at run time, but the fact that Cratera
supports it suggests it's not THAT bad.

self.super.super.super fails HARD, though, because the notion of
"super" there becomes bound up in the specific way the expression is
constructed. Consider this:

local more = foo.thing.other.more
more:why() -- what does self.super mean here?

The "more" object there has no idea that it's contained within
"foo.thing.other" unless you explicitly assign the value of "super" in
the object -- at which point that works just fine in current Lua
without any modifications at all -- or if you do what Python does and
you have . return a binding object instead of the object itself. But
tracking the whole call-time super chain adds an arbitrary amount of
overhead to every function call expression even if it's never going to
be used.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Coda Highland
On Tue, Nov 27, 2018 at 9:49 AM Soni L. <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Soni L.
Umm, you realize I made Cratera? I thought I made that explicit, but maybe I didn't.

I was replying to someone who had some incorrect ideas about composition.

Sorry for the confusion.

On Tue, Nov 27, 2018, 15:12 Coda Highland <[hidden email] wrote:
On Tue, Nov 27, 2018 at 9:49 AM Soni L. <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Lua Needs

Coda Highland
On Tue, Nov 27, 2018 at 2:30 PM Soni L. <[hidden email]> wrote:
>
> Umm, you realize I made Cratera? I thought I made that explicit, but maybe I didn't.
>
> I was replying to someone who had some incorrect ideas about composition.
>
> Sorry for the confusion.

You might have made that explicit and I just missed it. My apologies
on that point.

But you replied to... um... me. And I'm pretty sure I've got my head
on straight when it comes to composition.

So there's definitely some confusion here. Not anything that's an
actual problem, I just think I might have missed a point somewhere.

/s/ Adam

123