|
wellwhoopdedooo posted:No, the essence of inheritance is that SubClass is a BaseClass. The conversion is done by pointer offsets or other aliasing methods, not conversion functions. You are high. Your false distinction between some kinds of conversions and others is only preventing you from thinking constructively. You don't need some language's implementation of inheritance to encode the notion of an is-a relationship.
|
# ? Aug 12, 2011 15:43 |
|
|
# ? May 16, 2024 11:42 |
|
Inheritance "To an external observer, inheritance of T from U is indistinguishable from the presence of a conversion function from T to U." - Confucious I was simply saying that from an external observer inheritance of T from U is indistinguishable from the presence of a conversion function from T to U. And then people got all "oh no, inheritance is so much more than that" as if inheritance is also a mechanism used build definitions of types and functions without writing out a bunch of def foo(self) { return foo(convertToMySuperclass(self)); } definitions. Which was so surprising to me, being one of those high-on-Haskell types, I never knew that working-class languages could be so powerful!
|
# ? Aug 12, 2011 16:00 |
|
shrughes posted:To an external observer, inheritance of T from U is indistinguishable from the presence of a conversion function from T to U. Doesn't the inheritance relationship also imply the lack of a conversion function in the other direction? Consider code:
|
# ? Aug 12, 2011 16:23 |
|
Otto Skorzeny posted:Doesn't the inheritance relationship also imply the lack of a conversion function in the other direction? Well yeah, there is often an Unconvert : U -> Maybe<T>
|
# ? Aug 12, 2011 17:19 |
|
shrughes posted:Inheritance yes but with my definition of inheritance i'm right (also *still* I don't see how the presence of a function implies implicit casting within the language - you can have inheritance without allowing implicit casts )
|
# ? Aug 12, 2011 17:25 |
|
tef posted:(also *still* I don't see how the presence of a function implies implicit casting within the language - you can have inheritance without allowing implicit casts ) It doesn't. I never said that.
|
# ? Aug 12, 2011 17:29 |
|
Ahem.shrughes posted:Implicit casts are the same thing as inheritance. It looks a lot like that to me
|
# ? Aug 12, 2011 17:36 |
|
tef posted:Ahem. It doesn't to me. I never said every language must have implicit casts. Instead of assuming I'm wrong (which is practically impossible) you should assume you've misinterpreted my statements.
|
# ? Aug 12, 2011 18:21 |
|
inheritance is pretty useless anyway, just use decorators
|
# ? Aug 12, 2011 19:02 |
|
There is a difference, but it's based on the fuzzy rule of Liskov substitution. Or rather, it's based on the quite solid rule of Liskov substitution, but languages generally have other rules which interact poorly with such substitutions, so instead we have to base this around vague ideas of what sane programmers would actually do. So for example, Java's implicit conversion from int to long does not universally satisfy Liskov substitution because using an int instead of a long changes the type of an expression, which can impact overload resolution; but if you don't do semantically-distinguished overloads, it shouldn't matter. Similarly, upcasts can change overload resolution and member lookup, but if you're sane, it won't matter. But float->int conversions violate substitution basically as a matter of course.
|
# ? Aug 12, 2011 19:25 |
|
shrughes posted:Instead of assuming I'm wrong (which is practically impossible) shrughes.com posted:The only math I know is the kind useful for high school math contests.
|
# ? Aug 12, 2011 19:30 |
|
shrughes posted:Inheritance
|
# ? Aug 12, 2011 19:36 |
|
shrughes posted:It doesn't to me. I never said every language must have implicit casts. Instead of assuming I'm wrong (which is practically impossible) you should assume you've misinterpreted my statements. You said they were the same thing, so a language with inheritance would be a language with implicit casts, no? Alternatively your idea of 'the same' has been influenced by php edit: you're violating the lsp
|
# ? Aug 12, 2011 19:51 |
|
shrughes posted:Instead of assuming I'm wrong (which is practically impossible) you should assume you've misinterpreted my statements. Instead of assuming you're wrong, I assume you're trolling.
|
# ? Aug 12, 2011 20:39 |
|
Jethro posted:This is only true of inheritance without polymorphism. No it's not, the main point of the statement is that the form of polymorphism brought to you by inheritance is no different from a conversion function, and having no polymorphism. Having T1, T2, and T3 being children of B1, overriding some foo method, is not special in any way. You could have an API that ostensibly lacks polymorphism, that's just as powerful, by having by having separate functions convertT1toB1(T1) -> B1, convertT2toB1(T2) -> B1, convertT3toB1(T3) -> B1. Then instead of passing a T1 to a function that expects a B1 you just pass the value convertT1toB1(T1). Or, for the sake of convenience, your language can support implicit conversions. All inheritance gives you is one mechanism for defining such conversion functions, that's all.
|
# ? Aug 12, 2011 20:40 |
|
erm, wouldn't that call B1::foo? you're assuming dynamic dispatch which isn't always the case. In languages where functions are bound at compile-time, polymorphism and type conversion are distinct.
|
# ? Aug 12, 2011 20:49 |
|
TasteMyHouse posted:erm, wouldn't that call B1::foo? No because foo is virtual.
|
# ? Aug 12, 2011 21:17 |
shrughes posted:No because foo is virtual. Then your object is still of type T1 even if it masquerades as a B1. If it behaves as a T1 then it is a T1, even if the formal type is something else in the context. In my world, a type is defined by the operations on it. If two objects with the same interface have different actual operations performed by otherwise identical calls, then they are of different types.
|
|
# ? Aug 12, 2011 21:55 |
|
NotShadowStar posted:I've been working with Drupal a hell of a lot the last six months. The core developers behind it seem like reasonably intelligent people and understand PHP is a wretched language and keep it to the very basics: arrays, functions, very basic objects and it works okay-ish, if not excessively verbose. Unfortunately when I have to delve into PHP land I remember how god awful it its. It took me an entire afternoon to parse a CSV file because neither str_getcsv or fgetcsv could figure out new lines properly so it always just split CSV files into one gigantic flat array. Something that would take minutes to do in any other language. It works okay provided your newlines are at the end of a line and not within any value field ever
|
# ? Aug 12, 2011 21:58 |
|
nielsm posted:Then your object is still of type T1 even if it masquerades as a B1. If it behaves as a T1 then it is a T1, even if the formal type is something else in the context. So you say that string("hi") and string("hey") are of different types.
|
# ? Aug 12, 2011 22:00 |
shrughes posted:So you say that string("hi") and string("hey") are of different types. That's an interesting definition of "different behaviour".
|
|
# ? Aug 12, 2011 22:07 |
|
edit: never mind i'm not getting involved in this
|
# ? Aug 12, 2011 22:10 |
|
nielsm posted:If two objects with the same interface have different actual operations performed by otherwise identical calls, then they are of different types. Does that make the empty string (that is, the string that returns true when you call isEmpty()) of a different type to any other string? They do have quite distinct behaviour in that regard.
|
# ? Aug 13, 2011 01:23 |
|
nielsm posted:That's an interesting definition of "different behaviour". They seem to behave differently to me. For example, one of them returns 3 when you call size() on it, and the other returns 2. Also, if you call .charAt(1) you get a different result. All values of type B1 behave the way a B1 behaves. Even when they got converted from a function convertabertawoo() that took a T1 value (which behaves the way a T1 behaves). For example, suppose B1 = string and T1 = int. We can convert all ints to strings with convertIntToString(3) == "3" but some strings can't be converted back to ints. Also, just like all superclasses and subclasses, they behave differently in some ways and the same in others. If you pass a string (converted from an int) or a convertIntToString(n) to printStringToStdout, they'll behave exactly the same. Similarly, if you call size(s) or size(convertIntToString(n)), size will work exactly the same. So let's look at the specific case where virtual methods are involved. You define a virtual or abstract method foo on base class B1 and override it in subclass T1. What that does is it defines a function call_foo_B1 that takes a B1 and a call_foo_T1 that takes a T1. But more particularly, you've defined the convertT1ToB1 function to produce a B1 such that call_foo_B1 will behave on that value the way call_foo_T1 behaved on the original T1. Now you're going saying that some object exists that is still of type T1 even though we're now calling it a B1. What does that even mean? It's certainly the case that the B1 value is not necessarily a bit-by-bit copy of the T1 value. We need to perform some elementary arithmetic to convert between them. So we need to perform an actual manipulation to convert it back to a T1. But maybe you're thinking "Oh, but the part that does change is just the pointer, they're both pointers to underlying objects." Probably, but that's a pure implementation detail. Similarly with int and string, it takes some elementary arithmetic to convert from one to another. The fact that inheritance creates values that get converted at worst by some manipulation of pointer offsets is just a function of how compilers implement the types and conversion functions defined by inheritance.
|
# ? Aug 13, 2011 01:39 |
shrughes posted:I guess I see the logic. It just doesn't seem like a terribly useful mental model to me, though it surely can be useful in some formal proof situations.
|
|
# ? Aug 13, 2011 03:12 |
|
nielsm posted:I guess I see the logic. It just doesn't seem like a terribly useful mental model to me, though it surely can be useful in some formal proof situations. Any place where infinitely many degenerate types serves as a useful model is equivalent to a typeless one. Literally every function becomes a cast from one type to another. It's frankly pointless.
|
# ? Aug 13, 2011 04:24 |
|
1337JiveTurkey posted:Any place where infinitely many degenerate types serves as a useful model is equivalent to a typeless one. Literally every function becomes a cast from one type to another. It's frankly pointless. What model is that? It's certainly not the one I was talking about (which just pooh-poohs subtyping).
|
# ? Aug 13, 2011 05:01 |
|
shrughes posted:
|
# ? Aug 15, 2011 16:06 |
|
Don't remember if this was posted when it was originally written, but a nice vindication of most of what we discuss (except the PHP part, but I'm convinced no PHP programmer actually uses comments): http://www.webmonkey.com/2011/02/cussing-in-commits-which-programming-language-inspires-the-most-swearing/
|
# ? Aug 15, 2011 19:23 |
|
Scaramouche posted:I'm convinced no PHP programmer actually uses comments This is looking at commit messages, not comments. Still, php devs probably don't use those either.
|
# ? Aug 15, 2011 19:49 |
|
TasteMyHouse posted:This is looking at commit messages, not comments. Still, php devs probably don't use those either. ecommerce-mvc-cms-framework.fixed the colors.backup2.real.zip
|
# ? Aug 15, 2011 20:09 |
|
I think that if they're using source control at all they probably aren't the worst of the PHP programmers.
|
# ? Aug 15, 2011 20:17 |
|
That sure is some pretty, pretty, HTML.
|
# ? Aug 18, 2011 07:12 |
|
Jabor posted:That sure is some pretty, pretty, HTML. 220 instances of <div class="wrap" can't be wrong.
|
# ? Aug 18, 2011 07:19 |
|
Jabor posted:That sure is some pretty, pretty, HTML. Jesus loving asschrist, that is bad.
|
# ? Aug 18, 2011 07:23 |
|
Well, for free it seems dec-oh. http://muse.adobe.com/pricing.html
|
# ? Aug 18, 2011 08:00 |
|
(I apologize for the length of this post, but you really have to see this in all its glory.) Ladies and gentlemen, I give you The Invoice Print File Join Method. It starts out reasonable enough. There are 15 checkboxes that determine what types of invoices to print. Therefore there could be up to 15 files that have already been written to disk. So obviously we need 15 StreamReaders and 15 ArrayLists. code:
code:
code:
The following code ensues for each file, i.e. 15 times: code:
Now we have to find the iChoosen file: code:
We round things off with a nice, simple if-else chain. code:
|
# ? Aug 18, 2011 08:56 |
|
LOOK I AM A TURTLE posted:(I apologize for the length of this post, but you really have to see this in all its glory.) kill me
|
# ? Aug 18, 2011 09:36 |
|
LOOK I AM A TURTLE posted:Bravo
|
# ? Aug 18, 2011 10:55 |
|
|
# ? May 16, 2024 11:42 |
|
LOOK I AM A TURTLE posted:I saw this in production code before. Sadly, I fixed it and I can't be bothered to dig through subversion, but it was very similar. A dozen or so constructs, with hardcoded (identical) UI elements for each, a few boolean flags, three ArrayLists, some Strings. And lots and lots of if statements. When I rewrote the class to use a HashMap and proper OOP, I think it ended up being about a tenth of its original size.
|
# ? Aug 18, 2011 14:51 |