code logs -> 2010 -> Thu, 27 May 2010< code.20100526.log - code.20100528.log >
--- Log opened Thu May 27 00:00:29 2010
00:21 Reiv[Graduate] [orthianz@Nightstar-22771ff8.xnet.co.nz] has joined #code
00:26 You're now known as TheWatcher[T-2]
00:29 You're now known as TheWatcher[zZzZ]
00:32 Derakon[AFK] is now known as Derakon
00:44 Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has joined #code
01:38 gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has quit [[NS] Quit: Z?]
01:55 AnnoDomini [annodomini@Nightstar-70e08728.adsl.tpnet.pl] has quit [[NS] Quit: Peels.]
02:00 Reiv[Graduate] [orthianz@Nightstar-22771ff8.xnet.co.nz] has quit [Connection reset by peer]
02:15 Reiv[Graduate] [orthianz@Nightstar-2d24cd24.xnet.co.nz] has joined #code
03:01
< celticminstrel>
Searching through the __dict__ probably isn't the best way to do this, but it's better than having a giant if...elif...elif...elif in a function... then again, having a dictionary of callback functions would work too...
03:01
<@ToxicFrog>
Dictionary of callbacks plz
03:02
<@Vornicus>
<3 dictionaries
03:08
< celticminstrel>
It's only slightly easier to use the class's internal dictionary, so dictionary of callbacks would be fine; but then would I have to pass the self parameter explicitly?
03:10
< celticminstrel>
The (albeit slight) advantage to examining the class's dictionary is that I can simply define a new member function with the chosen naming convention and it will "automatically work".
03:10
< celticminstrel>
Whereas with the callback dictionary I need to both define it and add it to the dictionary.
03:10
<@Derakon>
Celticminstrel: you can do {'foo': self.processFoo} and not have to pass "self" around.
03:11
< celticminstrel>
Ah, that looks like it could be what I would want...
03:20
<@ToxicFrog>
Derakon: auto-closing of methods? Sweet.
03:39
<@Derakon>
TF: yeah, I do it all the time at work for dialog event handlers.
03:39
<@Derakon>
self.onClick, etc.
04:22 Vornicus [vorn@ServerAdministrator.Nightstar.Net] has quit [[NS] Quit: ]
04:24 Vornicus [vorn@ServerAdministrator.Nightstar.Net] has joined #code
04:24 mode/#code [+o Vornicus] by Reiver
05:08 celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has quit [[NS] Quit: *whistles* Did you hear something?]
05:42
<@ToxicFrog>
\o/
05:42
<@ToxicFrog>
All I need is xchat_hook_server, xchat_hook_print, and xchat_plugingui_*
05:43
<@ToxicFrog>
And maybe xchat_gettext, although I'm wary of binding undocumented functions.
05:43
<@ToxicFrog>
xchat_hook_fd stays unbound because I can't think of a way to bind it that isn't horribly unsafe.
05:44
<@Derakon>
Why are you writing an IRC bot?
05:44
<@ToxicFrog>
I'm not (yet).
05:44
<@ToxicFrog>
I'm writing a Lua plugin for xchat so I can finally replace this utility DSO I've been carting around since xchat 2.2.
05:50
<@ToxicFrog>
Once I'm done that I probably will port my old mapbot from its (terrible) coroutine-based framework to xchat-text.
06:36 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has quit [Operation timed out]
06:39 SmithKurosaki [Smith@Nightstar-26933809.dsl.teksavvy.com] has quit [Ping timeout: 121 seconds]
06:43 Derakon is now known as Derakon[AFK]
06:44 SmithKurosaki [Smith@Nightstar-5e45a1c6.dsl.teksavvy.com] has joined #code
06:46 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has joined #code
06:46 mode/#code [+o ToxicFrog] by Reiver
07:38 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has quit [Operation timed out]
07:39 Orth [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
07:40 SmithKurosaki [Smith@Nightstar-5e45a1c6.dsl.teksavvy.com] has quit [Ping timeout: 121 seconds]
07:41 Reiv[Graduate] [orthianz@Nightstar-2d24cd24.xnet.co.nz] has quit [Ping timeout: 121 seconds]
07:41 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has joined #code
07:41 mode/#code [+o ToxicFrog] by Reiver
07:41 SmithKurosaki [Smith@Nightstar-0a57481d.dsl.teksavvy.com] has joined #code
08:46 Orth [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Client closed the connection]
08:52 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
08:58 You're now known as TheWatcher
09:15 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Connection reset by peer]
09:19 AnnoDomini [annodomini@Nightstar-70e08728.adsl.tpnet.pl] has joined #code
09:20 mode/#code [+o AnnoDomini] by Reiver
09:21 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
09:58 Tarinaky [Tarinaky@Nightstar-b613f47a.adsl.virginmedia.net] has quit [Ping timeout: 121 seconds]
10:11 Tarinaky [Tarinaky@Nightstar-9b0dcd91.adsl.virginmedia.net] has joined #code
10:12 Rhamphoryncus [rhamph@Nightstar-bbc709c4.abhsia.telus.net] has quit [Client exited]
11:12 gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has joined #code
11:14 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Connection reset by peer]
11:21 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
11:35 Vornicus is now known as Vornicus-Latens
11:51 Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has quit [Client closed the connection]
12:01 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Connection reset by peer]
12:08 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
12:16 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Connection reset by peer]
12:22 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has joined #code
14:39 Tarinaky [Tarinaky@Nightstar-9b0dcd91.adsl.virginmedia.net] has quit [Operation timed out]
14:55 Tarinaky [Tarinaky@Nightstar-70878730.adsl.virginmedia.net] has joined #code
15:30 Reiv[Graduate] [orthianz@Nightstar-68f66f01.xnet.co.nz] has quit [Ping timeout: 121 seconds]
15:39 PinkFreud is now known as PinkCoffeeZombie
15:43 celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has joined #code
16:49 Reiv[Graduate] [orthianz@Nightstar-41c10dd9.xnet.co.nz] has joined #code
16:54 Tarinaky [Tarinaky@Nightstar-70878730.adsl.virginmedia.net] has quit [Operation timed out]
17:08 Tarinaky [Tarinaky@Nightstar-1c1774a2.adsl.virginmedia.net] has joined #code
17:30 Reiv[Graduate] is now known as Reivles
17:34 Derakon [Derakon@Nightstar-1ffd02e6.ucsf.edu] has joined #code
17:34 mode/#code [+o Derakon] by Reiver
17:34
<@Derakon>
Morning, folks.
17:42 Attilla [Attilla@Nightstar-c56d6882.threembb.co.uk] has joined #code
17:42 mode/#code [+o Attilla] by Reiver
18:07 AbuDhabi [annodomini@Nightstar-9440674e.adsl.tpnet.pl] has joined #code
18:08 AnnoDomini [annodomini@Nightstar-70e08728.adsl.tpnet.pl] has quit [Ping timeout: 121 seconds]
18:18 Derakon [Derakon@Nightstar-1ffd02e6.ucsf.edu] has quit [[NS] Quit: Leaving]
18:32 Rhamphoryncus [rhamph@Nightstar-bbc709c4.abhsia.telus.net] has joined #code
18:38
< celticminstrel>
Ghosting automatically changes your nickname, right?
18:38
< Tarinaky>
No.
18:38
< Tarinaky>
Not unless the server's weird or your client is.
18:39
< celticminstrel>
Oh. Well, never mind then.
18:41
< celticminstrel>
When a nickname is already in use, is it the client that automatically selects a different one?
18:41
< Tarinaky>
Yes.
18:42
< celticminstrel>
So, response to 433 should be "choose different nick, ghost, change nick".
18:50
< celticminstrel>
...so, does 451 mean that a successful NICK command has yet to be sent? Or that a USER command has not been sent? Or does it mean that the nick has not been registered with NickServ? I was assuming the latter, but now I'm thinking that's likely not the case...
18:52
<@ToxicFrog>
celticminstrel: well, if you read the RFC, you should note three things:
18:52
<@ToxicFrog>
- 451 is described as ERR_NOTREGISTERED
18:52
< celticminstrel>
Yes.
18:52
<@ToxicFrog>
- NickServ is not mentioned anywhere in the RFC, but
18:53
<@ToxicFrog>
- there is a section named "Connection Registration"
18:53
< celticminstrel>
Ooh, okay. The assumption about NickServ, by the way, was before I actually looked it up in the RFC.
18:57 Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has quit [Ping timeout: 121 seconds]
18:57
< celticminstrel>
Supposedly NICK is supposed to be sent before USER, but it seems to work the other way round as well.
18:58
< celticminstrel>
Which is a good thing, really.
18:59
< celticminstrel>
...and this library send PASS last of all despite the RFC saying it must be sent first. Lovely. Good thing I don't need PASS.
18:59
< celticminstrel>
^sends
19:08
<@ToxicFrog>
IIRC, the RFC says that NICK and USER are allowed in any order, but that NICK is recommended first
19:09 Vornicus-Latens is now known as Vornicus
19:10
< celticminstrel>
I think it said NICK first was required... but only between servers, I guess.
19:11
< celticminstrel>
Which a client/bot doesn't care about.
19:12
<@ToxicFrog>
Yes.
19:13
< Namegduf>
NickServ isn't in the RFC in any form; connection registration refers to providing a nick and such to be connected, and is unrelated to Services registration.
19:13
< celticminstrel>
I did read that section after you pointed me to it. :)
19:13
< Namegduf>
Services is an external program utilising the protocol and not taken account of within it, as a whole.
19:14
< celticminstrel>
Are the services at all standardized? They seem to be slightly different on all the networks I frequent...
19:14
< Namegduf>
No.
19:14
< celticminstrel>
I'm feeling an urge to improve this library, for some reason.
19:15
< celticminstrel>
^ sorry, TF pointed me to it, not you.
19:15
< Namegduf>
There's some "IRCv3" extensions which do add standardised things
19:15
< Namegduf>
Such as SASL authentication during connection registration.
19:16
< celticminstrel>
For some reason, the base class doesn't even pong. Sure, there's a second subclass that does, but why would anyone want a class that doesn't pong?
19:17
< Namegduf>
Sounds like they're obsessed with subdividing functionality between classes that inherit from each other.
19:19
< celticminstrel>
They search the class dictionary to see if a callback is defined for a particular response, rather than providing stubs for every possible response. I dunno whether that's really bad, but the "Rethink this, seriously" comment suggests that there could be a better way to do it. (And while providing stubs sounds like it'd work, it's also probably not the best way since that means you'd have hundreds of stub methods.)
19:20
<@ToxicFrog>
Yeah, personally, I think 'search the object for a method with this name, none found? skip" is better than stubbing everything out
19:20
<@ToxicFrog>
Or providing a dictionary of callbacks as a data member.
19:20
< celticminstrel>
True, it could provide a "register callback" interface or something, I suppose...
19:21
< celticminstrel>
A little more work for the extender, then, but not that much.
19:21
<@ToxicFrog>
You wouldn't even need that; self.callbacks["ping"] = \x -> send ("pong "..x)
19:22
< celticminstrel>
...what?
19:22
<@ToxicFrog>
...what?
19:22
<@ToxicFrog>
I'm pretty sure that's not legal python but I thought it got the idea across :/
19:22
< celticminstrel>
It does, yeah; I suppose you're suggesting something like lambdas?
19:23
< celticminstrel>
self.callbacks["ping"] = lambda x: send("pong " + x);
19:24
<@ToxicFrog>
Yeah.
19:24 * ToxicFrog kind of ended up with a bastardized hybrid of python, haskell, and lua there~
19:24
< celticminstrel>
Hehe.
19:25
< Namegduf>
The issue there is that you could onyl have one callback.
19:25
< Namegduf>
A user adding their own callback for ping would turn off ping replies.
19:25
< Namegduf>
"whoops"
19:25
<@ToxicFrog>
Yeah. But providing methods has the same problem.
19:26
< Namegduf>
Yeah, but that's why you might want to "rethink" the way it is.
19:26
<@ToxicFrog>
xchat uses a callback-registration approach, where the callbacks run in reverse order of registration and can 'eat' the event
19:26
< celticminstrel>
Well, maybe that could be solved by making 'callbacks' a dictionary-like utility class rather than an actual dictionary...
19:26
<@ToxicFrog>
Preventing later callbacks, xchat's internal handlers, both, or neither from seeing the event.
19:27
< celticminstrel>
The thought just popped into my head of using exceptions to "eat" callbacks. <_<
19:27
< celticminstrel>
^um, events, sorry
19:29
<@ToxicFrog>
"using events to eat callbacks"?
19:30
< celticminstrel>
?
19:30
<@ToxicFrog>
Just wondering what you meant by that.
19:30
< celticminstrel>
Using exceptions to eat events. 9_9
19:30
<@ToxicFrog>
Aah.
19:30
< celticminstrel>
Oh, I see you must've misinterpreted my correction. Sorry.
19:31
<@ToxicFrog>
...so every function would end with 'raise irc.EventHandlerEatNoneException' or something?
19:31
<@ToxicFrog>
Sounds...messy. What's wrong with return?
19:33
< celticminstrel>
Nothing, I guess.
19:33
< Tarinaky>
Exceptions are, be definition, messy.
19:33
< celticminstrel>
To be honest, they're probably about equivalent, at least in terms of neatness of code.
19:33
< Tarinaky>
My understanding is they're best used to handle exceptional behavior.
19:33
< celticminstrel>
So, might as well just use return then.
19:34
< celticminstrel>
I said the idea popped into my head; I never said it was a good idea. :P
19:43
< Rhamphoryncus>
IRC is a bastard protocol. It will resist all attempts of *good* code organization
19:45
< Rhamphoryncus>
Rather than exceptions you could consider a singleton. Python has a NotImplemented singleton returned by certain operator methods
19:46
<@ToxicFrog>
Rhamphoryncus: a good framework can hide a lot of that, though.
19:46
<@ToxicFrog>
Also, the discussion isn't implemented vs not implemented
19:46
< Namegduf>
There's a non-crack way to do this.
19:46
<@ToxicFrog>
It's "after this callback runs, should other callbacks be allowed to see this event"
19:46
< Namegduf>
You can return *a value*
19:46
< Namegduf>
To indicate this kind of thing
19:46
<@ToxicFrog>
Namegduf: yes, that's what I suggested
19:46
< Namegduf>
This is how InspIRCd module hooks work
19:47
<@ToxicFrog>
That's how xchat hooks work, that's how insp hooks work, that's how most sane event-handling callback systems work.
19:47
< Rhamphoryncus>
Aye, I'm not suggesting you use NotImplemented (except maybe for for a stub). What I mean is created your own like EatEvent
19:47
< Rhamphoryncus>
I really hate how gtk has you return true/false all the time. Maybe it's the best option in C, but in python it's unnecessarily vague
19:48
< Rhamphoryncus>
Even C could use an enum
19:51 * ToxicFrog nods
19:52
< Tarinaky>
I thought enums were a C++ feature?
19:52
< Tarinaky>
The C equiv would be #defines
19:52
< Rhamphoryncus>
Nope, C has them too
19:53
< celticminstrel>
Yep.
19:53
< celticminstrel>
...how is a singleton better than a constant?
19:53
< Tarinaky>
Singletons allow you to control the order of initialisation.
19:54
< Tarinaky>
Constants do not.
19:54
< celticminstrel>
Initialization of what now?
19:54
< Tarinaky>
The constant/singleton's contents.
19:54
< Rhamphoryncus>
But they're rarely used because.. well, C is stupid, heh. Maybe because the type it creates isn't too obvious and because they often do mixing of bitfields where you really want defines
19:54
< Rhamphoryncus>
Tarinaky: wrong kind of singleton. You're thinking of "OMG I'm not a global, honest!"
19:54
< Tarinaky>
Rhamphoryncus: Oh. Misread, sorry.
19:55
< Rhamphoryncus>
Tarinaky: I'm talking about a dummy value who's identity is the only thing meaningful, like None
19:55
< Tarinaky>
Rhamphoryncus: What's this kind of singleton?
19:56
< celticminstrel>
^ whose! "who's" means "who is"!
19:56
< Rhamphoryncus>
celticminstrel: the real point is so that you can say "return EatEvent" (or whatever). It's explicit. Although you could define it as "EatEvent = 7", that's unnecessary and may lead to people hardcoding 7. Better to use "EatEvent = object()" (or define your own class so it gets named)
19:56
< Rhamphoryncus>
celticminstrel: boo :P
19:57
< celticminstrel>
So, either use 'EatEvent = object()', or use 'class EatEvent: pass'?
19:57
< Rhamphoryncus>
or 'class EatEventType(object): pass; EatEvent = EatEventType()'
19:58 * Rhamphoryncus blames the english language for being stupid about possession
19:58
< celticminstrel>
Very true. 9_9
19:59
< Rhamphoryncus>
I can honestly say I've never seen "who's vs whose" mentioned before. Even on those pages talking about proper use of possession
20:00
< celticminstrel>
That last example seems a bit more than necessary; a user could return EatEventType instead of EatEvent.
20:00
< celticminstrel>
And... wow, re
20:00
< celticminstrel>
ally?
20:01
< Rhamphoryncus>
Well, arguably it should be _EatEventType to indicate privacy
20:01
< Rhamphoryncus>
aaand to get more complicated you could override __new__ to ensure further instantiation doesn't happen
20:02
< Rhamphoryncus>
It starts to get pretty silly though
20:03
<@ToxicFrog>
Or you could just return a string~
20:04
< Namegduf>
What the hell is going on
20:04
< Namegduf>
When I looked away people were talking about enums, well and good
20:04
< Namegduf>
But when I look back its this overengineered stuff to simply return a constant.
20:05
< Namegduf>
If the language can't do type-safe enums, which Python can't because it doesn't enforce type-safety, a string is pretty much equivalent, yeah.
20:07
< celticminstrel>
Gah, lag from Chrome-hang.
20:07
< celticminstrel>
So, which is better? The class, or the string?
20:08
< Rhamphoryncus>
Namegduf: strings encourage people to use the string as the constant, which is error prone
20:08
< Namegduf>
Rhamphoryncus: No more error prone than anything else in non-typesafe languages
20:09
< Rhamphoryncus>
I do use strings when I've got several modes to track, but when I'm returning just one possible value? I'd rather it be named
20:09
< Namegduf>
You do have several values.
20:09
< Namegduf>
If you only had one value, it'd be equivalent to no return value.
20:09
< Rhamphoryncus>
None vs EatEvent?
20:09
< Namegduf>
Right.
20:09
< Rhamphoryncus>
arguable
20:09
<@ToxicFrog>
Or EatEventAll vs EatEventPlugins vs None
20:09
< Namegduf>
You could just define EatEvent = 1
20:10
< celticminstrel>
Huh?
20:10
< Namegduf>
Or something
20:10
< celticminstrel>
What's the difference between those two?
20:10
< Namegduf>
Not a class, just a constant global variable.
20:10
<@ToxicFrog>
Or let's go the whole hog, have it return a function that when passed a callback will return true if the callback is allowed to see it and false otherwise!
20:10
< Rhamphoryncus>
problem there is you go to print it out and you just get 1, rather than EatEventAll
20:10
< celticminstrel>
...um, what, ToxicFrog?
20:10
< Namegduf>
Why would you be printing it out?
20:10
< Rhamphoryncus>
debugging
20:11
< Namegduf>
Why is this such a significant usecase as to warrant additional complexity in the software?
20:11
< celticminstrel>
What about just EatEvent = 'EatEvent'?
20:11
< Rhamphoryncus>
*shrug*
20:11
< Namegduf>
That sounds like it'd work, too, despite looking funny.
20:12
< celticminstrel>
What, the thing I posted?
20:12
< Namegduf>
Yeah.
20:12
< Rhamphoryncus>
maybe EatEvent = '_EatEvent' to indicate the string is private?
20:12
< celticminstrel>
I dunno how that'd make much difference.
20:12
< Rhamphoryncus>
it's slight, yes
20:17
< Rhamphoryncus>
I should have commented on composing handlers instead. Much more interesting subject
20:22
< Rhamphoryncus>
inheritance is inadequate, but callbacks are crude. They're just a mechanism, with no suggestion of what's the correct thing to do
20:24
< celticminstrel>
Huh?
20:37
< Rhamphoryncus>
Replacing a dummy default callback is one thing, but a callback provided by another plugin? That's got to be wrong
20:38
< celticminstrel>
...
20:39
< Rhamphoryncus>
Similar problem with multiple inheritance. Two unrelated classes providing the same method? There is no correct choice on which method should be dominant. It's just wrong.
20:40
< Namegduf>
There's a simple solution, really
20:40
< Namegduf>
Forbid multiple inheritance where methods overlap.
20:40
< Rhamphoryncus>
Namegduf: aye, that's my general opinion
20:41
< Tarinaky>
Multiple inheritance - especially public inheritance - should only occur in a small number of cases anyway. :/
20:41
< Namegduf>
Alternatively, you could require that your class doing the multiple inheritance overrides the method.
20:41
< Namegduf>
And implements what should be done.
20:41
< Namegduf>
Again simple, but much less restrictive.
20:43
< Rhamphoryncus>
I'm kinda curious about how to avoid using inheritance, ever. Replace it with mixins, composition, and interfaces (or ABCs)
20:44 * Namegduf has never had trouble in languages without inheritance
20:44
< Namegduf>
Interfaces provide valuable abstraction, and composition can be a useful tool.
20:44
< Rhamphoryncus>
I've never used one in a serious fashion. Maybe C, but it doesn't count
20:44
< Namegduf>
It doesn't?
20:45
< Rhamphoryncus>
C doesn't provide most of the other features common to OO like GC, methods, and operator overloading
20:45
<@McMartin>
C counts for composition, but not inheritance.
20:46
<@McMartin>
"It doesn't count unless the compiler knows about it" is the basic principle here, I think.
20:46
<@McMartin>
You can of course build a coding discipline that acts *like* inheritance.
20:46
<@McMartin>
But if you allow that, then hand-writing hexadecimal machine code is actually logic programming just like Prolog is.
20:47
< Namegduf>
McMartin: I think you missed the "without" part
20:47
< Rhamphoryncus>
I do mixins and composition in python (and arguably most base classes serve as mere mixins anyway)
20:47
< Namegduf>
Rhamphoryncus: I didn't realise you were restricting yourself to OO languages.
20:48
< Namegduf>
I'll agree that C isn't one.
20:48
< Rhamphoryncus>
Namegduf: classes tend to be linked with OO :)
20:48
< Namegduf>
Rhamphoryncus: I had no idea you were restricting yourself to classes.
20:49
< Rhamphoryncus>
inheritance tends to refer to classes?
20:49
< Namegduf>
Yes, and you said "without" it.
20:49
< Namegduf>
You didn't say "without inheritance but still with classes", I misunderstood, sorry.
20:49
< Namegduf>
Anyways, I've found myself not to miss inheritance when not available, except as a way of creating abstract interfaces.
20:49
< Rhamphoryncus>
My intent was "given what classes are used for, I wonder about using X instead..."
20:50
< Namegduf>
Leading to "fun" things in C sometimes
20:50
< Rhamphoryncus>
C doesn't use classes in such a fashion to begin with, so it's not comparable
20:51
< Namegduf>
So... you're wondering if you can emulate design patterns for inheritable classes using these other features, rather than implement similar functionality differently?
20:52
< Rhamphoryncus>
And how much common usage actually matches the inheritance pattern, rather than a mixin or composition
20:52
< Namegduf>
Ah.
20:53
< Rhamphoryncus>
For instance, a single abstract base class with many direct subclasses, none of which are further subclassed. The base class is never instantiated. That's just a mixin
20:56
< Rhamphoryncus>
I have a file like that right now. 15 subclasses and an simple base class. There was actually actually a second abstract base class, a subclass of the first, but it was refactored out
20:58
< Rhamphoryncus>
That's where it gets a little hazy, treating python as just mixins and composition. That second base class fits more clearly as inheritance of a mixin, otherwise it wouldn't still be a "mixin type" (conceptually)
21:04
< Rhamphoryncus>
That's assuming I modify the language to have either a normal class (which can be instantiated and can have mixins) or a mixin (which can't). The naive approach fails for that reason. I could think up ways to get it to work, but I'd like to examine how other languages in similar situations handled it
21:05 Attilla_ [Attilla@Nightstar-27696e15.threembb.co.uk] has joined #code
21:06
< Rhamphoryncus>
If I were to allow mixins to include other mixins that'd effectively be inheritance, but conflicts wouldn't be allowed, no type checking would be included by default, and normal classes would default to "final" (in the java sense, cannot be further subclassed)
21:07
< Rhamphoryncus>
instantiation would also have to be redesigned, since that's the major use case for cooperative super calls
21:07 Attilla [Attilla@Nightstar-c56d6882.threembb.co.uk] has quit [Ping timeout: 121 seconds]
21:08 Attilla_ is now known as Attilla
21:09
< Rhamphoryncus>
Defaulting to final would have big consequences, and is undesirable for a language like Python, but I feel really uncomfortable about subclassing a class that was never designed for it, ya know?
21:11
< Rhamphoryncus>
Python didn't originally allow subclassing of list/str/dict, and added it later, but oops 90% of the methods are done directly in C and use only the base class's versions, so you can't override them anyway
21:12
< Rhamphoryncus>
why? Because there's all sorts of hidden assumptions. They're used internally by the class itself. It couldn't use them that way if they could be overridden
21:12
< celticminstrel>
Why not?
21:13
< Rhamphoryncus>
I'd have to dig around to find specific examples. Mostly it's just the nature of C though. They're designed collectively
21:13
< Rhamphoryncus>
Heck, half of them aren't even public functions. They're common helper functions
21:14
< Rhamphoryncus>
Even though conceptually two methods may be equivalent, neither calls each other through a public interface
21:15
<@ToxicFrog>
I suspect it's something like: method foo maps to C function py_foo; method bar maps to py_bar
21:16
<@ToxicFrog>
Foo calls bar.
21:16
< Rhamphoryncus>
Maintaining that, rather than redesigning it to use a hierarchy over which public methods you should override to affect other public methods, leads you to composition
21:16
< Rhamphoryncus>
yup
21:16
<@ToxicFrog>
However, the way this is implemented, foo calls py_bar() rather than going back out into python to call self.bar
21:16
<@ToxicFrog>
So if you redefine bar in python, too bad, the original version of foo is still calling the C version of bar directly.
21:16
< Rhamphoryncus>
exactly
21:19
< Rhamphoryncus>
So, even if you did allow some public methods to be overridden in a well defined fashion, what you'd end up with is mixin+composition. The core parts are kept isolated and don't care what you think. The public parts are just a mixin
21:22
< Rhamphoryncus>
A true subclass wouldn't distinguish a base's public from private. It would access both just as easily, and wouldn't violate any assumptions because it would be designed at the same time as the base
21:22
< Rhamphoryncus>
By the same person too
21:25
< Rhamphoryncus>
inter-unit vs intra-unit
21:50
< celticminstrel>
Hm; what's the difference between H and G in the WHO response?
21:50
< celticminstrel>
It probably doesn't matter, but I'm curious.
--- Log closed Thu May 27 21:50:17 2010
--- Log opened Thu May 27 21:50:31 2010
21:50 TheWatcher [chris@Nightstar-b4529b0c.zen.co.uk] has joined #code
21:50 Irssi: #code: Total of 22 nicks [5 ops, 0 halfops, 0 voices, 17 normal]
21:50 mode/#code [+o TheWatcher] by Reiver
21:51 Irssi: Join to #code was synced in 53 secs
21:52
<@ToxicFrog>
celticminstrel: G is set away. H is not.
21:52
< celticminstrel>
Well, that could be useful.
21:53 * ToxicFrog snrks at this commit message
21:53
< celticminstrel>
Ah! Gone and Here, I'm guessing.
21:53
<@ToxicFrog>
"Unit test: build and run, observe HM commands are absent"
21:53
<@ToxicFrog>
"QA test: ditto"
21:53
<@ToxicFrog>
"Regression risk: the very concept implies a level of effectiveness and stability never achieved"
21:55
< Namegduf>
XD
21:55
<@McMartin>
HM?
21:56
<@ToxicFrog>
Hardware Monitor
21:58 Derakon[AFK] is now known as Derakon
22:10 Zed [Zed@Nightstar-e4835f03.or.comcast.net] has joined #code
22:53 Reivles [orthianz@Nightstar-41c10dd9.xnet.co.nz] has quit [Ping timeout: 121 seconds]
23:12 AbuDhabi [annodomini@Nightstar-9440674e.adsl.tpnet.pl] has quit [[NS] Quit: DEATH.]
23:49 Attilla [Attilla@Nightstar-27696e15.threembb.co.uk] has quit [Ping timeout: 121 seconds]
23:54 You're now known as TheWatcher[T-2]
23:56 You're now known as TheWatcher[zZzZ]
--- Log closed Fri May 28 00:00:16 2010
code logs -> 2010 -> Thu, 27 May 2010< code.20100526.log - code.20100528.log >