| firedraco (5413) | ||
Then I suppose I'm not sure what the problem you have is. Just use the 'C' classes everywhere and if a B is needed somewhere then you can just pass it and inheritance will take care of turning it into a B for you. | ||
|
|
||
| ne555 (4041) | ||||||
For the second part
| ||||||
|
|
||||||
| xerzi (570) | |
|
Yah I don't see what has to be coordinated between 3 devs, perhaps an example of what each developer is responsible for (using your minecraft case) ? In any case I disagree that a feature should be included simply to standardize a single case. The other 2 devs should follow the standard/method used by the first. | |
|
Last edited on
|
|
| andywestken (1950) | |
|
I found the opening post a bit difficult to follow, but if I understand correctly you were asking if there are languages which allow you change the behavior of object instances dynamically. If I got that right, then you might be interested in actor programming languages, like Humus. Actor Languages http://c2.com/cgi/wiki?ActorLanguages Humus Overview http://www.dalnefre.com/wp/humus/humus-overview/ In Humus, the BECOME statement tells an instance to use a new behavior when responding to a message. Andy PS While I've seen mention of these actor languages from time to time, and read a bit about them, I've never tried to use one. And though the ideas been around a fair while, it' never been popular. Why has the actor model not succeeded? http://www.doc.ic.ac.uk/~nd/surprise_97/journal/vol2/pjm2/ http://www.doc.ic.ac.uk/~nd/surprise_97/journal/vol2/pjm2/ | |
|
Last edited on
|
|
| m4ster r0shi (2045) | ||||
|
--[[ Maybe Lua [1] is what you're looking for. (BTW, you can feed this post to a Lua interpreter as it is, and get meaningful output. I did it several times as I was writing it.) Lua doesn't have built-in support for OOP, but it offers some powerful features that allow one to easily emulate it. These features also allow one to do what I think you want here. In Lua, everything that represents some kind of non-primitive data is a table. You can store anything you want (numbers, strings, functions, other tables) in a table and you can also use anything you want as an index to a table. Not surprisingly, the most straightforward way to emulate a C++ class is to use a table: ]]
--[[ Notice that I didn't actually define a type here. I just created an object with the properties I wanted. If I want to create more Entities, I'll have to copy the one I created here [2]. Well, not actually copy it. Just set it as the metatable to the newly created Entities: ]]
--[[ Setting e1's metatable and Entity's __index member to Entity has the following consequence: Whenever you try to read data from e1 using an index that doesn't exist in e1, the Lua interpreter tries to access the Entity table using that index before returning nil (the Lua non-value). Now, the very same features that allow emulation of classes, also allow emulation of inheritance: ]]
--[[ [1] http://www.lua.org/ [2] http://en.wikipedia.org/wiki/Prototype-based_programming ]] | ||||
|
Last edited on
|
||||
| coder777 (2378) | ||||
Imagine that you pass a pointer to an object that does perfectly what you want to a function and all of a sudden it does something else! The consequences would be that programming becomes a game of pure chance | ||||
|
|
||||
| L B (3327) | |||||||||||||||||||
I don't understand where I went so wrong.
http://www.cplusplus.com/forum/lounge/84738/#msg454287 http://www.cplusplus.com/forum/lounge/84738/#msg454249 As far as I can tell it was the fourth time...
I'm really confused how I cam across so unclear. I thought that by specifying what I was looking for in the thread title and in the post, plus a one-use fallback in the post, I could perchance get the attention of someone who happened to know more than me and happened to know of such a language. Instead, I got the single-use fallback a multitude of times in various languages. I've decided such a language must not exist for the feature in it to be so confusing and unheard of that only design patterns could allow for it. And in case it still is not clear, I was looking for an entire language that had the feature I described as a built-in language feature, not as a design pattern. Design patterns solve problems that languages don't solve, and considering I gave specific emphasis to looking for a language, I don't feel bad for hammering on the design patterns you all gave. Thank you for your time, everyone, and sorry for wasting it. | |||||||||||||||||||
|
Last edited on
|
|||||||||||||||||||
| firedraco (5413) | ||
Then you can simply create C's from the B's since the C's by definition have no other data members. I just don't think that such a feature would exist because it would only help in a very specific case but could easily cause issues without tons of checks for other cases. | ||
|
|
||
| L B (3327) | |||||||||
| |||||||||
|
Last edited on
|
|||||||||
| firedraco (5413) | ||
Ok, I think I see what you are saying now... I think the problem is that you want to have two (possibly separate) objects that both can reference the same data "base" except that one of the objects hasn't made provisions for that. You could try making the 'C' class just contain a pointer or something to the B "base" class and have a conversion to a B (so that it could be converted easily), but that's just another design pattern. I'm not completely sure why you *need* a language feature for this though. It's sort of like saying you want a language feature for converting an integer to a string and back. Not bad or anything but not having it doesn't prevent you from doing it. | ||
|
|
||
| L B (3327) | |
|
Those are two completely unrelated things. Converting between strings and numbers is, essentially, changing the representation of a serialized form from one type to another unrelated type so that it is easier to deal with the serialized form as needed. The two types are unrelated and have different representations in memory, along with incompatible behaviors and public interfaces. Allowing for an existing instance to be converted, in-place from the perspective of the code and the programmer, to an instance of a subtype, is, essentially, enabling new behavior that previously was not possible, and this new behavior is fully compatible because the public interface is the same and does not affect code that expects it to be at the very least a more abstract type. Obviously giving a string to a function that expects a number primitive or a number primitive to a function that expects a string will cause serious problems. But with the language restrictions imposed on classes, it is no problem to give a std::ofstream to a function that expects a std::ostream. The idea is that design patterns solve problems that are not solved by the language and have no trivial solution within the bounds of the language's features. If a design pattern has to be used at all, you're not using the correct language, or the language is flawed in terms of the language's goals. Theoretical use-case based on real-world scenario: Minecraft has a Block class. The Buildcraft mod has a TransportPipe class that somehow extends the Block class, because transport pipes are blocks. The MorePipes addon mod has a FastTransportPipe class that somehow extends the TransportPipe class. It is necessary, due to popular request by lazy users, to be able to change existing transport pipes into fast transport pipes without manually breaking and replacing the existing pipes and causing items being transported to spill out. Due to the poor design of the no-longer-maintained Buildcraft mod, which is still compatible with Minecraft and still highly popular with no alternative, the only way to implement the feature requested is to literally call functions to break the pipe and place the new one in its place, except you have no way of preserving the state of that pipe. Thankfully, Minecraft, Buildcraft, and MorePipes all used the XYZ language, which allows for converting existing instances into further-derived class instances, so the TransportPipe object can be converted into a FastTransportPipe object, changing it's physical appearance to players and allowing it to transport items more quickly. If they hadn't used language XYZ for their code, they'd have all been screwed. Unfortunately language XYZ doesn't exist so they are all screwed. Thankfully this scenario is fictional and the Buildcraft mod is under active development, so the MorePipes mod author can ask the Buildcraft mod author to implement a design pattern that allows the feature. This should not be needed, however, because it completely violates basic OO principles. You shouldn't have to accommodate every possible extension to a class you make; the language you use should. I can't imagine having to write a class and then write code to account for every single possible class that could ever be created to extend my class. That completely goes against the ideas behind Object Oriented Programming. If no class/OO contracts are violated, no changes should have to be made to code. If a class or instance does not say "you can't extend me!" then you should be able to extend it without changing what you are extending. Many of the design patterns that have been suggested involve accounting for expansion to the original via behaviors stored in the individual instances of the original class. It's a clever design pattern, but it completely bypasses object oriented programming with classes and inheritance and language features that can do it with less hassle and more chance for compiler optimization. My point is, it doesn't violate anything, it has a use, it fixes a problem otherwise solved by design patterns. It's a language feature, and should be, which is why I originally asked if there was a language that had such a feature. You've all shown me there is not such a language for it. It is clear to me there is not such a language for it. I can use design patterns. I can create my own language. All I asked for was practicality, all I got was hard reality. Can I be left alone now? You all clearly do not agree with my idea and can't see any benefit to it. I'm tired of asking for white-chocolate ice cream and getting chocolate and vanilla ice cream with white-chocolate sprinkles. | |
|
Last edited on
|
|
| firedraco (5413) | |||
Wait. So I thought you had to keep the original B objects around even though you had created the new C object? If you don't, then why can't you just replace the B object with the C object (made from the B object)? Where a B object is needed it will be converted for you because C is a B.
I just don't understand how your idea requires a new language feature. It seems like just deriving C from B would work fine to me, but obviously I'm missing something that prevents that from working. | |||
|
|
|||
| L B (3327) | |||||
| |||||
|
Last edited on
|
|||||
| firedraco (5413) | |
|
So basically what you want is to be able to modify B "in place" to turn it into a C but still allow all of the previous B references to stay valid (pointing at the new C), right? I guess the only way you would be able to do it is go through all the list of references that point to that B and point them to the new C that you just made. You could try using placement new on the address of the B to construct that C with the B (maybe making a copy to make sure you don't screw anything up) but that would assume that C doesn't have any extra data or that you have enough room to do it. I would assume that if it was present as a language feature that you would have to do some form of the above steps somewhere. EDIT: But like you said, I don't think there is a language that has this as a feature. | |
|
Last edited on
|
|
| L B (3327) | |||
| |||
|
|
|||
| Lachlan Easton (57) | ||
Because C may have more members than B, so to convert B into C it would need to grow in memory when there may not be enough space. | ||
|
|
||
| L B (3327) | |
| Like I said, it has to be a language feature. The language implementation would account for all that. | |
|
|
|
| firedraco (5413) | ||
That's what I meant. The implementation would have to do it for you at some point. Obviously you wouldn't see it. | ||
|
|
||
| L B (3327) | |
| Ah, sorry - misunderstood. | |
|
|
|
| Abramus (220) | ||
Doesn’t every dynamic language worthy this name have this "feature"? I mean, in Python, for example, an object contains some special fields: __class__ specifies its type, and __dict__ references a dictionary with the object’s attributes. By changing those fields you can easily morph an arbitrary object into an object of any other type. There is no need for the creator of that other type to do anything unusual. This way you can accomplish your goal without any design pattern. Or am I missing something?
| ||
|
Last edited on
|
||