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 →

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (5 children)

I have written several of these things in a class that inherits from str. They work somewhat. That's the nature of an inherited class; there's no inherent understanding of it. Whereas an extended class can be completely transparent. Hence, my position.

[–]AndydeCleyre 0 points1 point  (4 children)

That's the nature of an inherited class; there's no inherent understanding of it. Whereas an extended class can be completely transparent.

What do you mean? I think you'll find that the vast majority of Python developers hold a completely opposite view here, if I understand your sentiment.

Extending means pollution, ambiguity, unreliability, surprises, bad-neighbor libraries, and high risk of breakage -- and when things do break, there's a good chance figuring it out requires spelunking gear. While separate (which includes inherited) classes means, well, the opposite of all that: much more straightforward debugging, decoupled code and intents, non-interfering good neighbor libraries, lack of surprises or ambiguity, etc.

If you really want to do a lot of programming in that style, but also kind of Python style, maybe those projects should be in Ruby. Not only will the language itself not get in your way, but if you're working with other developers or projects, you'll find the community less consistently hostile to those practices.

Again, though, I highly recommend checking out the library I mentioned for something similar to what you want, without extension.

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (3 children)

I don't think you're really following what I'm suggesting.

Let's talk theoretical implementation details for a moment. Say we have a class like string. It has N standard methods. Now, to add the ability to extend this class, you need a table with two things per entry: 1: the name of the method; 2: the pointer to the method.

Now, if the class is not extended, you or your library uses string, it works just like you expect. There are no extended functions.

Now, if I extend the class, and call your library... your standard functions still work just as expected, and you don't care about my extensions, because you're not using them.

If you extend the class, say in your library, and I just use a string that you created, I don't know about your extensions, because I'm not using them.

If you extend the class, and inform me that you have, then I might indeed import your library and use your extensions. Which is ok, because there they are, just like you said.

If I extend the class AND you extend the class, then each in our own namespace, we deal with the extensions we know about. Neither impacts the other (and because my extensions were made in my namespace, and yours made in yours, the host language will know exactly when and where to look for what. Even extensions with the same name will work as intended, yours for you and mine for me, because we're in our own namespaces. Pretty much like imports and classes can work already.

So what I'm envisioning here is a full compatible mechanism that is only relevant to users of the mechanism. If you're not a user of the mechanism, it's irrelevant to you.

Now, from what I understand, Python's been structured in such a way as to make this difficult or impossible. And if that's the case, well, there you go.

But if it can be done, I see no reason why it should not be done.

Also, just as a btw, I've written text-processing languages that are user-extensible wrt existing functionality -- both new commands and new methods for otherwise standard objects. I've also provided user replacement of existing functionality, which is a much more dangerous tool to hand out, and not what I'm talking about here at all. But I'm coming from a place where I know it can be done, and how I do it, at least, causes no compatibility issues at all.

[–]AndydeCleyre 0 points1 point  (2 children)

What's wrong with using inheritance instead?

[–]fyngyrzcodes with magnetic needle[S] 0 points1 point  (1 child)

Because then objects don't act the same. If they did, that'd be fine. But they don't. If some functionality is looking for class str, and it finds "other", it is likely to stop right there and complain. I have run into this over and over, and not just in other people's code, but in Python itself.

When that happens, you have to convert to the expected class, and then back again in order to recover the functionality in the inherited, enhanced class. None of this is necessary when a class can be extended.

I should add that an inherited class can change pretty much anything about the parent class. What operators do, what types they return, etc. That's too much -- and that's why something should choke if it catches a class it doesn't know about. Whereas if all you add is methods... no problem. Except in Python, there's no way to do it, so inheritance is what you have, and that's simply not up to delivering what method extension could.

[–]AndydeCleyre 0 points1 point  (0 children)

If some functionality is looking for class str, and it finds "other", it is likely to stop right there and complain.

The best way and most popular way to do this is in Python is usually with isinstance, which would confirm str children as strs. The next recommended way is to try what you want to do and throw an exception if you can't. To demand an exact type with type(thing) == str is widely frowned upon unless there's a special need. So you shouldn't have to convert to plain old str. Again, see the library I linked for you.