Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Mat Marcus [EMAIL PROTECTED] wrote: --On Monday, September 01, 2003 3:37 PM -0300 Fernando Cacciola [EMAIL PROTECTED] wrote: Joel de Guzman [EMAIL PROTECTED] wrote in message One can think of an optionalT as conceptually a specialized but nevertheless, *IS-A* T, with the added specialization that it can be in a dead-uninitialized state. Maybe we'll call it a zombie object, undead object, you name it ;-) Hmmm. I'm not so sure about this. When I hear the phrase optionalT IS-A T with an added specialization I am reminded of the phrase a Square IS-A Rectangle with an added specialization which usually gets folks into trouble. [Theoretical aside: I still see optionalT as a sum/union, e.g. T + nil/ T | nil. That is I don't think we really want A + B B (the sum/union of A and B) to be a subtype of A.] This is the model that I was trying to *sell* from the very very start when optional first came out for review. I never really understood why people didn't see it that way. This is exactly the reason why I suggested looking at other languages: to be able to get a solid grasp of the concepts behind such a *thing* so as to be able to answer with utmost certainty the question: : what is optional? Some people say it is a container. Not! Some people say it is like a pointer that can be NULL. Not! And this uncertainty leads us to confusion, and, ultimately: missguided syntax and semantics. My attempt to image optionalT as conceptually a specialized but nevertheless, *IS-A* T, with the added specialization that it can be in a dead-uninitialized state. Is a feeble attempt to re-sell the idea of the concept that will be immediately obvious to the OO programmer. I never really understood why I wasn't able to sell the idea that an optionalT is *REALLY REALLY REALLY* nothing else but a union of T and nil. Here's a question that tries to get to the crux of the pointer-like interface matter. Should T* and optionalT both be models of a pointer-like syntactic concept? Definitely No! I imagine that those who would answer yes do so because they may want to write generic code that uniformly handles pointers and possibly uninitialized variables. Those who answer no to the above question may prefer to write code that uniformly handles T and optionalT. As you know, my (current) answer is no. There may be a third group who want both. The problem is that I find that the pointer-like interface is distracting, but that may be because I'm unfamiliar with the use-cases where you might want to handle T*'s and optionalT's uniformly or even replace raw pointers with optionalT's, since pointers also bring allocation issues with them. Instead I have been mainly focused on replacing T's with optionalT's. This is why I gravitate towards having an optional that models a syntactic concept such as PU that makes no mention of pointer-like syntax. I agree 200%. I think the *only* meaningful argument against this was posed by Brian. That, in C++, you cannot make XT be a drop-in replacement of T because implicit conversion will not allow code such as: struct A { void foo(); } template class T void bar(T t) { t.bar(); } bar(A()); bar(XA()); // HERE Unless: class XT : public T {...}; But then again, that's just a technical impediment. By the way, I would also like to thank you for your work on optional and your contributions to boost. I also appreciate your open discussion of the design of optional and optional-like classes. My posts are just those of a potential user who is interested in finding the right point in the design space for my needs. If my use cases or arguments prove useful to others or if optional is influenced to meet more of my needs, then of course I will be pleased. If not, I'm still learning about the design space from you and others on this list, so I benefit either way. Same here. I would certainly hope to hear more from you. In fact, I wish to hear more from the type-theory people such as Mat and Vesa ;-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
On Tue, Sep 02, 2003 at 09:05:59AM +0800, Joel de Guzman wrote: My attempt to image optionalT as conceptually a specialized but nevertheless, *IS-A* T, with the added specialization that it can be in a dead-uninitialized state. Is a feeble attempt to re-sell the idea of the concept that will be immediately obvious to the OO programmer. I never really understood why I wasn't able to sell the idea that an optionalT is *REALLY REALLY REALLY* nothing else but a union of T and nil. It's been pointed out before, but to re-emphasize it: from a type-theoretic standpoint, it is not the case that optionalT-isa-T. Rather T-isa-optionalT. (Dog-isa-Animal because Animal has more possible values.) I don't mind the suggestive conceptual analogy/similarity, but when you get down to technicalities, the isa relationship doesn't hold in the same direction you're saying (in your first sentence above). I agree 200%. I think the *only* meaningful argument against this was posed by Brian. That, in C++, you cannot make XT be a drop-in replacement of T because implicit conversion will not allow code such as: struct A { void foo(); } template class T void bar(T t) { t.bar(); } bar(A()); bar(XA()); // HERE Unless: class XT : public T {...}; But then again, that's just a technical impediment. As I just mentioned in a previous mail, if bar() has the foresight to expect this, it can use an adapter in its implementation to smooth out this issue. (E.g. template class T void bar(T t) { adapt(t).bar(); } ) As a final aside, I think much of this thread is degenerating into Parkinson's Bicycle Shed[*], with respect to is it a pointer/container/X? At this point, I think we know what set of methods should be in the interface (indeed, there could be methods both to return pointers and references; both to throw/fail-undefinedly, etc.) and the names/documentation issues will fall out with more experience. Just MO. [*] See bottom of http://www.boost.org/more/discussion_policy.htm -- -Brian McNamara ([EMAIL PROTECTED]) ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
--On Monday, September 01, 2003 9:52 PM -0400 Brian McNamara [EMAIL PROTECTED] wrote: [snip] As a final aside, I think much of this thread is degenerating into Parkinson's Bicycle Shed[*], with respect to is it a pointer/container/X? At this point, I think we know what set of methods should be in the interface (indeed, there could be methods both to return pointers and references; both to throw/fail-undefinedly, etc.) and the names/documentation issues will fall out with more experience. Just MO. [*] See bottom of http://www.boost.org/more/discussion_policy.htm I'm not sure that we are discussing the shed just yet. I think we have finally identified some of the key design alternatives and their rationales. But it is true that this thread has received a number of posts now and I'd hate to think that it is degenerating into noise. For this reason, and for the fact that I have some upcoming deadlines at work, I'll summarize what I see and where I stand now, then I'll step back a bit for a while. Summary of thoughts on the existing optional: It now seems to me that the idea of the pointer-like interface wasn't so much to treat pointers and optionals uniformly. Rather, what I'm hearing is that the pointer-like interface was chosen because of the familiar syntax and idioms with regard to checking for initialization. Additionally, optional deliberately does not require a throw or assert upon uninitialized use, preferring to leave this as a QoI issue. I can respect this set of design decisions, and optional in this form certainly has its uses. If optionalT grows to allow more transparent co-existence with T (implicit construction, smooth tie interoperability) then I expect it will become even more useful. Summary of thoughts on an alternative to optional: While optional offers much of what I need, I still have trouble with the pointer-like interface, largely for reasons of explainability. I believe that clients/maintainers of the libraries that I write would be distracted and confused by the a pointer-like interface or container-like ideas. What I really want is a simple class template that models Possibly Uninitialized variables with no mention of pointers at all. Perhaps I'd call it Maybe, or SmartVar. How would I specify it? Well at a high level my (sloppy, late night) design goals would include: * Interface driven by the desire to replace dumb variables with smart variables -- that is variables that check that they've been initialized before use, offer smooth interoperability with dumb T's (e.g. assignment and implict operations where sound). * Where transparency is not feasable forego pointer-like syntax to avoid any appearance of relation to pointers/iterators * The action upon use while in uninitialized state shall be specified or even specifiable (throw/assert/etc.). * Backdoor to uninitialized storage available, e.g. unsafe_reference() * Works reasonably well with tie() * No double storage penalty Clearly optional is a fine piece of work and satisifies many of these goals. If it satisified a few more of them then I might find it usable in my current projects, perhaps completely ignoring the pointer-like protocol. For now I may work an a small lib that directly addresses the goals above. As I mentioned at the start, I've spilled enough words on this so I'll step back for a bit now. But if others are interested in working together in this area (on or off list) then perhaps we might collaborate. Thanks again to Fernando, Joel, Brian, Dave G. and others for discussing all of this. - Mat ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Fernando Cacciola [EMAIL PROTECTED] wrote: First of all, let's not confuse syntax with semantics. optional HAS strict value semantics. No it does not. The accessors have pointer behavior! -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Fernando Cacciola [EMAIL PROTECTED] wrote: vector::begin returns an object with operators * and -, yet these objects are not pointers, and once that is learned, people do not think they are pointers. Huh? pointer semantics (behavior) does not mean that they have to be pointers. -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Fernando Cacciola [EMAIL PROTECTED] wrote: Joel de Guzman [EMAIL PROTECTED] wrote in message There's a lot of experience with it in other languages. Why not leverage that? Haskell::Maybe for instance. Do you know of anything else besides Haskell? No. I don't, and I took the time to investigate Maybe looking at Haskell programs using it. As Brian pointed out, it is not so easy to port Maybe to C++ because its usage is extensively supported by Haskell features that are not present in C++. The most fundamental point is that being Haskell a pure functional language there is no possibly undefined behaviour to worry about, so Maybe doesn't need to address this issue as optional does. Agreed. -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Fernando Cacciola [EMAIL PROTECTED] wrote: Joel de Guzman [EMAIL PROTECTED] wrote in message Direct initialization: opt = 1 seems right since this operation is never undefined. This would mirror variant's interface. Ok. Direct value accesing via implicit conversion: int i = opt seems wrong because this is the operation that can lead to undefined behaviour. Doesn't have to be undefined behaviour. Aren't you throwing an exception or something? variant throws throws a bad_get exception when you get a reference to a T which is not the held type. I don't see a problem why you can't do something similar. -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
--On Monday, September 01, 2003 2:57 PM -0300 Fernando Cacciola [EMAIL PROTECTED] wrote: Mat Marcus [EMAIL PROTECTED] wrote in message [snip] After reading the documentation more carefully I learned that optional models pointer behavior. I spelled out how the code might look: boost::tie(*begin, *end); file://sorry, ASSERT looks too strange Wow, that looked strange to me. I don't think of begin and end as pointers at all here. Right, they're not pointers and you shouldn't see them as such. I think that your report is very important because it shows me that while one may expect the need for special constructs in order to 'access' an optional value, such need isn't there when one wants to initialize or assign an optional. It was very reasonable to expect optional to work with tie as that is just assignment and assignment is always defined. Yes, it seems like optional is just the sum (disjoint union) of nil and T, so why not allow implicit construction and assignment from T. Of course, I realize that there may be technical obstacles to getting optional to work transparently with tie in this way(doesn't tie normally create a tuple of references?). [snip] I think that OptionalPointee's documentation failed its purpose. That concept is intended to be exactly what you proposed, except that I left initialization/assignment aside. The concept just explains that the operator * and - syntax is used to access the a value that is possibly uninitialized, WITHOUT implying that a model of this concept IS a pointer. The concept was invented precisely to allow the same syntax to be used with entities that are NOT pointers. The particular choice of operators is to allow pointers to be models of the concept. Perhaps it is the name which is misleading. It can be renamed as PossiblyUninitialized if that helps. OptionalPointee is a bit misleading for me. Also I work in a group that is ultimately responsible for transferring our technology to the product teams, so I need to be able be convince others that my code will be maintainable. I will probably choose to avoid the pointer-like operator interface since I think it makes optional harder to use/explain. I'm not sure that PossiblyUninitialized is the best name for the concept, but it works a bit better for me since it's more about Optional and less about (the arguably distracting) Pointee. And it should incorporate initialization and assignment. [snip] Great. This should definitely help with my use cases. I'm still curious whether there will be a recipe to use optional with tie. And if there is such a recipe I wonder whether pointer will still be a model of the Concept. - Mat P.S. Doesn't ML have offer an option type? Haven't had a chance to look into this yet. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
On Monday, Sep 1, 2003, at 11:31 America/Denver, Joel de Guzman wrote: Fernando Cacciola [EMAIL PROTECTED] wrote: vector::begin returns an object with operators * and -, yet these objects are not pointers, and once that is learned, people do not think they are pointers. Huh? pointer semantics (behavior) does not mean that they have to be pointers. But would the following hold if p and q are optionlint? *q = 1; p = q; *p = 2; assert(*q == 2); ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Fernando Cacciola [EMAIL PROTECTED] wrote: Even if I agree with you that an optionalT should not be a T, an optionalT is definitely not a pointer to T. Definitely! If HTML had blinking banners I think I'd use one to state this :-) Nor should it model a pointer. That was my point and the point of others who dislike *opt. Yet iterators are not pointers either but they do use operators * and - Iterators are not pointers, but they model the pointer. Right. In fact, looking at it more closely, I *could* almost agree with you that an optionalT is not a T. There is in fact a getter function (get). In fact all three (tuple, optional and variant) have a get function. That's fine, yet, here again, the optional does not jive well because it returns access *by pointer* whereas both tuple and variant return access by reference. This get() issue we agree should be fixed. Agreed. If there's a way to get at the values through a generic get function that unifies the access of optional with variant such that I can think of optional as an optimized specialization of variantT, none, I would be very happy. With such an interface, I can simply ignore the pointer-like interface, if you wish to keep it ;-) Thanks you very much! And BTW, kudos for such a well engineered library! Spirit has been using it since v1.7 and I am very happy with it. The comments I gave so far are merely my opinion. You are of course free to have your own preferences :-) Keep up the good work! Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Optional, tie, and iterator_adaptor
Gregory Colvin [EMAIL PROTECTED] wrote: On Monday, Sep 1, 2003, at 11:31 America/Denver, Joel de Guzman wrote: Fernando Cacciola [EMAIL PROTECTED] wrote: vector::begin returns an object with operators * and -, yet these objects are not pointers, and once that is learned, people do not think they are pointers. Huh? pointer semantics (behavior) does not mean that they have to be pointers. But would the following hold if p and q are optionlint? *q = 1; p = q; *p = 2; assert(*q == 2); No, because the model is half-baked, which is exactly the reason for my dislike. -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost