Question - super on middleclass

General discussion about LÖVE, Lua, game development, puns, and unicorns.

What should I do with super?

1. Keep it like it is now. Performance isn't that important.
0
No votes
2. Use the debug.getinfo-based solution, even if it is a bit "hacky".
0
No votes
3. Move it to a middleclass.extras
0
No votes
4. SuperClass.method(self) is fine. Ditch super.
9
100%
 
Total votes: 9

User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Question - super on middleclass

Post by kikito »

I'd like to pick the collective brain about something.

As you may know, I'm in the process of changing the way super works on middleclass.

Right now it basically modifies the scope of each method, by placing a "pantom" scope, using fenv and newenv. This is how I do it:

Code: Select all

  local fenv = getfenv(method)
  local newenv = {super = superDict} -- when 'super' is referenced inside method, in reality it will reference superDict (defined elsewhere)
  setmetatable( newenv, {__index = fenv, __newindex = fenv} ) -- any other reference inside the method is redirected to the previous environment
  setfenv( method, newenv ) 
I like it because it is short and simple. I don't like it because the syntax isn't particularly satisfying, but more importantly every reference has now a "penalty"; everything is "rooted over" newenv, most of the times failing and going back to fenv. And that re-routing takes some time. Nothing too huge, but it's there. Even in functions that don't need to use super.

1. Current solution

Code: Select all

MySuperClass = class(...)

MySubClass = class('MySubClass', MySuperClass)

function MySubClass:initialize(name)
  super.initialize(self) -- super is found on newEnv.
  self.name = name -- but the 'self' and 'name' references also are looked on newEnv first, and on fenv when that fails
end

function MySubClass:foo()
  print(self.name) -- this function doesn't use super at all, but it gets penalyzed anyway.
end
I've thought of another way of implementing this, which makes the super call itself a bit slower, but leaves the rest untouched (no more newenv). But that implementation also has something I don't like: in order for it to work, I would have to use debug.getinfo(2, 'f'), in order to get a reference to "the function where super is called" and do some magic from there. The syntax would remain the same, and performance would be improved, since super calls are not as common as regular variable access. But using debug functions for running production code is hacky - or so they seem to say on the lua-users wiki.

2. hacky solution with debug.getinfo

Code: Select all

function MySubClass:initialize(name)
  super.initialize(self) -- this first line is a bit slower than before...
  self.name = name -- the rest is unaffected, but I had to use debug.getinfo to make it work, and that is hacky
end
There's a third possibility, which is moving super to another module of middleclass.extras; You use it only if you want. But middleclass.extras already has lots of modules. I'd prefer not to add modules for everything. super seems a very nice feature and I'd like leaving it on the core lib, if possible. If I were to do this, I'd probably go with option 4:

3. Move it to middleclass.extras

Code: Select all

MySubClass:includes(Superable) -- without this line, the super reference doesn't work
function MySubClass:initialize(name)
  super.initialize(self)
  self.name = name -- but the rest is unaffected
end
Finally, the last possibility is just forgetting about super; I remove it completely from middleclass, and do it the pythonesque way:

4. snake-oriented super

Code: Select all

function MySubClass:initialize(name)
  MySuperClass.initialize(self) -- no penalty, very similar syntax
  self.name = name
end
This is tempting because it makes everything smaller and simpler. It makes the lib a bit more resilient; one less thing that can break. But it would mean admitting defeat :)

So, what do you guys think?

I'm attaching a poll, but will use it as a reference - I'm more interested in your comments. But if you don't have time to comment, please leave the inexpressive numeric feedback.
Last edited by kikito on Mon Jan 24, 2011 7:22 am, edited 1 time in total.
When I write def I mean function.
User avatar
leiradel
Party member
Posts: 184
Joined: Thu Mar 11, 2010 3:40 am
Location: Lisbon, Portugal

Re: Question - super on middleclass

Post by leiradel »

I voted on 4, because it opens up the possibility of middleclass supporting multiple inheritance.

Thanks,

Andre

Edit: I mean, 4 has always been there, but super doesn't go well with multiple inheritance in my opinion.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: Question - super on middleclass

Post by BlackBulletIV »

I also voted on 4. It looks good to me, and I like the fact that it improves performance. I like the super syntax (as my first language was ActionScript), but that looks like the best option to me. The syntax of option 4 actually reminds of C++, where you reference the class itself.
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: Question - super on middleclass

Post by TechnoCat »

#4
super was kind of confusing at first.
If I explicitly instance an object inside a class then it is much more straightforward.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Question - super on middleclass

Post by Robin »

I agree with those guys, but I don't have a really good reason. I just never liked the hackish super.
Help us help you: attach a .love.
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Question - super on middleclass

Post by vrld »

#4, because it stresses that MySubClass is a child class of MySuperClass. You could also switch roles to avoid confusion about . vs :

Code: Select all

function MySubClass:initialize(name)
    self:initializeSuper(MySuperClass)
    self.name = name
end
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Question - super on middleclass

Post by kikito »

Whoa, I didn't anticipate such a massive one-sidedness!

Pretty much everyone commenting dislikes super. That is a bit surprising :ultrashocked:

It's a bit too early to decide, I'll keep this up for a week, in case the non-pythonesque guys appear.

Thanks everyone for the feedback, I really appreciate it.
When I write def I mean function.
An00biS
Prole
Posts: 21
Joined: Thu Nov 13, 2008 9:55 am
Location: mapy.cz/?query=rajhrad

Re: Question - super on middleclass

Post by An00biS »

Voted #4.

I was going to add '#2 would be good too', but then I've read the posts above me and got reminded of the multiple inheritance. I prefer function to form, so 4 is the way to go for me. And I'm also cautious on performance topic - I remember reading a book on C++ saying: 'Designers of the language took care to make it as fast as pure C, because they knew that programmers would refuse a slower language, no matter the advantages'. I like the thought of it.

While the 'super' approach does look nice in code samples, it just doesn't go really well together with Lua IMHO.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Question - super on middleclass

Post by kikito »

An00biS & leiradel wrote: ... multiple inheritance ...
Just so it is clear; it's not possible to do multiple inheritance with middleclass; every class has a single superclass (except Object, whose superclass is nil). This is pretty much hard-coded into middleclass and I doubt it will change.

However!

There are mixins. They are basically lists of functions that you can "include" on any class. It's not as automatic as MI (you have to be a bit more careful in your constructor), but it offers the same functionality, and none of its problems.
When I write def I mean function.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: Question - super on middleclass

Post by BlackBulletIV »

The only problem with using SuperClass.method is that it's hard coded to the super class' name. Of course if you changed the super class, then you could easily do a find/replace, and using methods from a super class is somewhat hard coded anyway. But if hard coding the name was a problem, you could use self.super (like you were suggesting before kikito), however I'm not really sure about that syntax (doesn't sit well).
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 5 guests