In response to Falacy
Falacy wrote:
I am usually right, and I am not overly complaisant when everyone else is wrong.

There's a difference between 'thinking' you are right and being right.

If somebody is going to post something in the tutorial section, then it should be 100% accurate, 100% relevant, and 100% beneficial to BYOND design.

You're right, but by making a post explaining why you shouldn't use parent_type is not 100% beneficial to BYOND design, or DM, rather. That's like saying a class is 100% nonsensical in an object-oriented approach.

Feel free to read up on why you shouldn't use parent_type
http://www.byond.com/forum/?post=302547

I'm not gonna read it. You wasted your time and others' time by even making a post about it.

Should I know who you are? Or are you just another noob troll who has been around for barely a month, but tells stories about BYOND's history?

I should have probably mentioned how judgmental you are, too. On a side-note, I have been around long enough to know who the jester of this community is, which of course is you.
In response to Falacy
Falacy wrote:
The broken inheritance that parent_type provides should indeed be "anti-taught".

I'm going to get to this below, but it is, in fact, mathematically provable that parent_type does not break inheritance at all.

That is an accurate representation. By parent_typing your /gun/ammo to /datum, it strips it of the proper class data that you should be able to rely on.

It doesn't, because it simply places it in a new namespace. You're wrong because your underlying assumptions are that typepaths are an inheritance system, when they are not.

This is exactly what it does. By parent_typing an /obj as a /mob, you will no longer inherit /obj class data, but will instead be artificially classed as a /mob.

No, it does not. If you do

mob/myObj
parent_type = /obj


then /mob/myObj is still a subclass of /obj. It just that the typepath now provides different semantics, but /mob/myObj is a subclass. It inherits its behaviors from the /obj superclass and it fulfills requirements of the superclass and subclass, such as the Liskov substitution principle, which is going to come up again. Furthermore, the virtual machine is aware of the superclass-subclass relation, as demonstrated by this:

mob/myObj
parent_type = /obj

mob/Login()
var/mob/myObj/o = new
world << istype(o, /obj)


It does not work as a namespace, like you seem to think it does, namespaces would provide additional data

This is not how namespaces work in any language that I'm aware of. A namespace is simply an abstract container. There is not and never is additional data associated with it. I'm not even sure what additional data that would entail.

parent_type is an unnecessary full override that essentially creates an entirely new subtype.

This is wrong, assuming you mean subtype to mean subclass. When using the parent_type notation, the relevant class's superclass is the one indicated by parent_type. This is provably true using all formal definitions of a subclass (and especially the Liskov substitution principle, which really is one of the best tools in this case).

What it really comes down to is that this sort of subclassing is not a standard way of doing things, and, as is clear, you do not understand it, nor do you understand how it works. And this scares you.

The thing is, they are simply not scary. And if you understood object-oriented design, you would know this.

A namespace is more accurately comparable to a top level /datum.

No it's not. A top-level /datum is the closest thing BYOND and DM has to a 'pure' class. That is, a class with no associated methods or variables. The closest thing BYOND has to namespaces are typepaths.

It is confusing because /obj/X should behave as an /obj, not as a /mob.

This is true. Unfortunately, this is also regarding the strawman you set up, and it falters in an important way. What is wrong with something like this?

weapon
parent_type = /obj

sword
spear


It is abundantly clear there is nothing in the typepath to indicate what 'weapon' should act like. So, does this mean it should act like 'nothing'?

It is not beneficial because there are more practical, intuitive, and correct methods to create type paths.

Of course, these are practical and while unintuitive at first, they quickly become extremely apparent. Unintuitive does not mean wrong, and something that is unintuitive at first is not forever relegated to unintuitive. You should not let that first impression taint your view of things, for that limits your ability, vastly.

And as for correct? I'd really like to hear a good formal reason for how it is incorrect.

Because you've never used a more complex programming language and, and hell let's admit it, because you're not a real programmer, you can't conceive of how these may be properly used.
What was that you said about projecting?

This borders on non-sequitur, because it implies that I have never used a more-complex programming language, when I certainly have. If you want to dick-waggle about the number of languages I've used, there are at least 10, about half of those being languages that compile directly to machine language, and thus have a lot less hand-holding.

I'm not saying his example was wrong, just lacking.

Okay, then let me refine that statement: You're claiming he is wrong because his example is incomplete. I don't know whether that makes more or less sense, but perfect sense it clearly does not make.

If somebody is attempting to explain the Pythagorean theorem to you using an equilateral triangle, then yes, they are doing it wrong. Providing broken examples isn't exactly the best way to teach.

Clearly the point of the statement went over your head. It was to be taken in conjunction with the previous one.

You want me to explain why it isn't effective to create a procedure that does nothing but return another procedure?

Yes, I would like you to explain why encapsulation and separation-of-concerns/abstraction are poor programming practices.

Or why using parent_type to break inheritance isn't an acceptable practice?

This one I really would like you to explain, since it's abundantly clear using formal statements that inheritance is not broken.

That was the entire point of these discussions. As I said earlier, explaining things to you for a 4th time probably won't accomplish much. Just go back and reread things if you couldn't understand them on your first attempt.

If you believe that this is a discussion about object-oriented principles, then your knowledge is worse than I thought. This is simply a lot of discussion of how BYOND implements various things, which is related to OO design. It's obvious that it's not just that you don't understand, but you don't know that you don't understand, which is a lot worse.
In response to Popisfizzy
Urias wrote:
You're right
Indeed


Popisfizzy wrote:
You're wrong because your underlying assumptions are that typepaths are an inheritance system, when they are not.
Feel free to explain that

This is not how namespaces work in any language that I'm aware of. A namespace is simply an abstract container. There is not and never is additional data associated with it. I'm not even sure what additional data that would entail.
A top-level /datum is the closest thing BYOND and DM has to a 'pure' class. That is, a class with no associated methods or variables. The closest thing BYOND has to namespaces are typepaths.
Namespaces provide data that a /datum or library could provide; variables, values, functions/procedures, classes/types, etc. They are not, themselves, a class inheritance system, as you seem to think.

(and especially the Liskov substitution principle, which really is one of the best tools in this case).
If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.
Looking at your /gun/ammo example again, /ammo is a subtype of /gun. However, because of your parent_type usage, replacing a /gun with /ammo would break your design. This would not be the case if you were using DM's type casting properly (by simply not using parent_type).

It is confusing because /obj/X should behave as an /obj, not as a /mob.
This is true. Unfortunately, this is also regarding the strawman you set up, and it falters in an important way.
OK then, back to your example for the 50th time. /gun/ammo should behave as a /gun, not only as a top level /datum.

It is abundantly clear there is nothing in the typepath to indicate what 'weapon' should act like. So, does this mean it should act like 'nothing'?
Pretty much, it should act like 'nothing', yes. It should act as a top level /datum.

And as for correct? I'd really like to hear a good formal reason for how it is incorrect.
Using parent_type breaks the correctness of standard BYOND typing. Attempting to reference something, on an object that is using parent_type, will most likely not return the expected results.

Okay, then let me refine that statement: You're claiming he is wrong because his example is incomplete.
Again, not even claiming that he was wrong to begin with, just the incomplete part.

Yes, I would like you to explain why encapsulation and separation-of-concerns/abstraction are poor programming practices.
They aren't, but the redundancy of code provided in these overly simplistic examples is.

It's obvious that it's not just that you don't understand, but you don't know that you don't understand, which is a lot worse.
What was that you said about projecting?
In response to Falacy
Falacy wrote:
Feel free to explain that

It's funny, because I can actually use an example you provided below, thanks to your failure to understand object-oriented design and the Liskov substitution principle. The Liskov substitution principle states that if we have two classes A and B, and B is a subclass of A, then any object of type A may be replaced with B, then the program remains unaltered*. We can use the LSP as a heuristic of whether a particular relationship is an inheritance relationship or not.

More formally, if P is the statement "B subclasses A" and Q is the statement "the program remains unaltered*", then the LSP can be stated at Q if and only if (iff) P. Now, A := /foo and B := /foo/bar/parent_Type = /datum (a typepath relationship). When we do this, Q is false. Because LSP(P,Q) is true, then this means P is false.

Therefore, this Liskov substitution principle implies our relationship, a typepath relationship, is not an inheritance relationship.

Namespaces provide data that a /datum or library could provide; variables, values, functions/procedures, classes/types, etc. They are not, themselves, a class, as you seem to think.

No, namespaces are not a class. And I do not think they are. But they are a type of abstract container. As per Wikipedia, "A namespace (sometimes also called a name scope) is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols (i.e., names). An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces."

Note that typepaths, in conjunction with the parent_type variable, satisfy all these requirements. Thus, it's very clear typepaths are a type of namespace system, albeit one that is complex and much different from most languages' namespace implementation (which typically involves far different syntax). A namespace is not a class and has none of the properties of a class. It can not be instantiated, subclassed, etc.

A /datum, on the other hand, is just an approximation of a top type in DM. A class, by itself, has no way of resolving naming collisions and can not act as a pure container (i.e., it has to be instantiated).

A library also, clearly, is not a namespace. If you program a library without any namespaces, you have a huge chance of running into collisions, especially if it provides a lot of common functions.

If you're going to attempt referencing something in your defense, then your should probably try and understand it first.
If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.
Looking at your /gun/ammo example again, /ammo is a subtype of /gun. However, because if your usage of parent_type, replacing a /gun with /ammo would break your design. This would not be the case if you were using DM's type casting properly (by simply not using parent_type).

This is actually pretty hilarious, because you just demonstrated what I did above, and what you asked me to. You have shown that the typepath system is not an inheritance system. In your own words. This means you really can't attack me inanely for including the use of parent_type in my proof. So, I applaud you for proving your own statement, even if it was less rigorous.

In conclusion, typepaths are not an inheritance system. And I'm going to clarify that this does not mean parent_type breaks the inheritance system of typepaths. It means that the typepath system was never an inheritance system at all.

On the other hand, parent_type is an inheritance system, one that meshes together with typepath system by default. Below is another formal demonstration of this, with the following in mind.

[Root]/[Class]
// This is defined as the following.

[Root]/[Class]
parent_type = [Root]

[Class]
// This is defined as the following.

[Class]
parent_type = /datum


Above are some basic properties of the DM formal grammar. Some basic definitions we must work with. Additionally, to make things a little clearer, I'm going to break the relationships indicated by parent_type into two categories.

// Type one relationship, AKA 'implied' or 'default'.

foo/bar
foo/bar
parent_type = /foo

// Type two relationship, AKA 'explicit'

foo
bar
parent_type = /foo


Now then, onto the little proof.

As we did before, let P be the statement "B subclasses A" and Q be the statement "the program remains unaltered*". LSP(P,Q) = Q iff P, and LSP(P,Q) = true. Thus, Q iff P = true. Next, A := /foo and B := /foo/bar = /foo/bar/parent_type = /foo (a type one (implied-by-default) parent_type relationship). Because Q is true, then P is true. Therefore, a type one parent_type relationship is an inheritance relationship.

Next, A := /foo And B := /bar/parent_type = /foo (a type two (explicit) parent_type relationship). Because Q is true, then P is true. Therefore, a type two parent_type relationship is an inheritance relationship.

Therefore, by the Liskov substitution principle, parent_type relationships are a form of inheritance.

OK then, back to your example for the 50th time. /gun/ammo should behave as a /gun, not only as a top level /datum.

No. Because typepaths are not an inheritance system, and are closer to a namespace system, both of which were demonstrated above, the typepath relationship is semantic, not inheritance-related. The reason /obj/X should act like /obj is because that the /obj typepath gives the semantic implication that its subtypes (but not subclasses) should be, in same way, object-like (object here meaning the general, real-world usage of it).

Thus, as a consequence, it would be entirely valid for a subtype (not subclass) of /obj to be a datum, if that datum imparted some /obj-like quality. Perhaps you have a ghost-like object, for example, that is only visible to certain people, and is implemented via images. The problem with this, though, is that the base atom types (/area, /turf, /obj, and /mob) have such strong semantic associates with their classes that I'd say a good rule of thumb is that their subtypes should be strictly limited to subclasses.

Generating a new, top-level subclass, though, as I do with the /gun example, provides an entirely-new set of semantics, though. It is not longer required to be 'obj-like' or 'obj-related' but instead 'gun-like' or 'gun-related'. Its subtypes (not subclasses) should have some strong relationship to guns. And, thus, the /gun/ammo relationship is semantically valid.

In summary: /mob/myObj breaks the semantics imparted by the /mob typepath, while /gun/ammo does not. This is the most important difference.

Pretty much, as 'nothing', yes. It should act as a top level /datum.

And, as above, I greatly disagree on this point.


Using parent_type breaks the correctness of standard BYOND typing. Attempting to reference a general type path, on something that is using parent_type, will not return the expected results.

Something is correct only with regards to a formal specification. I assume your interpretation of the 'formal specification' is that A is a subtype of B implies A is a subclass of B. That's not impossible thanks to the default behavior of parent_type, but that behavior is also very simplistic and detrimental. It makes namespacing effectively impossible in DM, which hinders library development due to an inability to resolve collisions.

Thus, a good formal specification using current DM syntax would not require the specification you desire, meaning it is correct.

They aren't, but the redundancy of code provided in these overly simplistic examples surely is.

Redundancy is often heavily-associated with both encapsulation and abstraction. This is because what is often redundant in simple examples and abstract concepts becomes much less redundant and far more flexible when put into practice. Flexibility is very important in software design.

What was that you said about projecting?

You really haven't demonstrated strong knowledge about any of these topics yet. I stand by my original statement.

*By 'the program remains unaltered', I mean 'the program remains unaltered within certain specifications', as indicated by the definition Wikipedia gave.
Well, I gave up reading that book of a post after getting halfway through and realizing that every line was excessively overstated nonsense. I also give up attempting to explain basic concepts to you. Go back to programming your BYOND calculator library that only takes binary input, I'm sure thousands will find it notable.
I know mathematical proofs can be confusing when you first look at them, but come on. This is simpler than the proof that irrational numbers exist, which is a pretty damned simple proof. It's only basic mathematical logic and it's finished in a paragraph.
Falacy, I don't see how you can't understand this. Then again, I understood it before the proof.
Just going to point out something.

The proc that returned oview()? Yeah.
That proc can be easily modified later to return something else without the need of oview(), once the inexperienced programmer becomes more experienced and learns how to do it. Having a proc return oview() is not completely redundant, it opens up an easier door for beginners to change things later when they learn some new things.
I could demonstrate a simple example of why parent_type is useful for inheritance. I don't even need to complicate things here.

C++:
class Ball:public obj
{
public:
Ball();
};


DM:
Ball
parent_type = /obj


See, real simple. :P

If anything, it will function very similar to how C++ works. Of course the exception would be no parent_type variable in C++, but still.
Can someone give me a basic rundown of what the debate is about? I'd like to give my two cents/ wrap my head around this without reading three pages of "NO, UR RONG, IM RITE!"
In response to Bravo1
The big thing is that I'm claiming Falacy does not really understand object-oriented programming or object-oriented design (and I'm not the only one that believes this). He basically tried to demonstrate how he does understand it and... proceeded to show that he doesn't really understand it.
Well, from what I can see, this whole "parent_type" thing seems to be questioning what it does?

Really, it's just defining inheritance... isn't it?
Ex:
obj
Ball

//same as

obj/Ball

//same as

Ball
parent_type=/obj


Frankly I don't see how an argument could have arisen from such a simple variable.
He believes that there is something objectively incorrect with it. The problem is that this is entirely untrue.
Well, there's nothing wrong with it, but *using* it is actually kind of pointless because, why would you use parent_type when the first two examples are simpler?

The way I see parent_type: It's a built in variable that is used by DM often, but never has to be used by anyone developing DM, unless, y'know, they just feel like it.
I provide reasons for it here. Basically, the typepath system represents a complex namespace system, and recognizing this can be used to your advantage.
So DM hierarchy is actually a namespace that gallivants as a inheritance system for the sake of simplicity?
In response to Bravo1
Bravo1 wrote:
So DM hierarchy is actually a namespace that gallivants as a inheritance system for the sake of simplicity?

In a sense. That's the gist of it, though there's a bit more to it. Above, though (comment #47), I did write a simple, not-terribly-rigorous proof that the typepath system is not an inheritance system. This is something Falacy refuses to accept.
In response to Popisfizzy
Popisfizzy wrote:
In a sense. That's the gist of it, though there's a bit more to it. Above, though (comment #47), I did write a simple, not-terribly-rigorous proof that the typepath system is not an inheritance system. This is something Falacy refuses to accept.

Indeed, I refuse to accept that because it is completely and utterly wrong. So wrong, in fact, that I gave up on even attempting to explain the correct concepts to you. After that post you made, I have to assume that you are literally retarded, or just maliciously trolling to spread idiotically false ideas. To say that type paths are not the inheritance system of BYOND is ridiculous. A type path creates a parent child relationship where inheritance is derived. Using parent_type to break this relationship is unarguably wrong. Have you ever actually read the DM guide that you constantly direct people to? Because it explains this simple concept very early on (in the very first chapter, in fact), not that it is difficult for anyone with half a brain to figure out on their own.
And thus, the cycle resets itself. Where we are lost in BYOND's endless paradox of misconception, the universe can only do but one thing, expand our cycle so that even we may see beyond the BYOND, and so that we may see the mis-shaped future we have crafted, as it begins a new, so will we...
Explain it to me Falacy, I'm quite intuitive.

Explain how the DM heiarchy works in your simplest terms, and then explain how it's different from what pop is saying.

This way you both can get an objective view on the argument and I'm still 50/50 as to who to believe.

It's your best bet for closure on the subject.

Mind you: if you deny the request, I'll have to consider your point moot as someone who doesn't defend their subject likely doesn't believe in it.
Page: 1 2 3 4