
Beman Dawes wrote:
At 08:34 AM 3/4/2004, Peter Dimov wrote:
... a window is not a stream.
Agreed. A window is also not a pointer, even if all it actually contains is a smart pointer.
A 'window' with reference semantics is a pointer. But this is not the important issue here, see below. David Abrahams wrote:
You're still missing the point. The fact that the owning window constructs the child is an implementation detail that has nothing to do with the window structure/layout the user is trying to represent. The syntax for describing a window should be declarative, not imperative.
He later added:
Sure, though I would never call the function "add". I'd be looking for declarative DSELs like:
window("Warning: now entering twilight zone") [ text_field("my favorite color is:"), button("OK") | button("cancel") ]
And clarified that:
I'm not interested in the free/not free debate, and I don't have an opinion on it. I'm only interested in the syntax for building windows.
Douglas Paul Gregor agreed:
I'm solidly behind the proposals to use a DSEL for describing GUI elements. It's the right level of abstraction for the task.
In my opinion, this approach, while enticing, is misguided. What makes it dangerous is the consensus that is being built around it. Please allow me to present the opposite point of view. A GUI DSEL that masks the underlying architecture can do more harm than good across all programmer skill levels, and, with all due respect to Beman, a stream-based DSEL can be even more damaging, especially to novices (its intended audience). What is the most important task of a Hello World program? It must teach the programmer the fundamental principles of the underlying language or library. In our case, given a GUI architecture that does not support unowned/free widgets and clearly distinguishes between ownership and containment, a Hello World program must clearly communicate these principles to the user. A stream-based DSEL can be even more deceiving, it not only masks this important principle, but also establishes a false analogy with respect to stream I/O, and can lead a novice programmer to believe that "C++-like" equals "stream-based". It is also important to show that the on_delete member of a window is a plain ordinary boost::signal that can be manipulated independently of its window owner, and that the only thing that wait_for_signal has in common with GUI is that it automatically avoids one particular form of deadlock by starting the message loop when invoked from the same thread that is supposed to fire the signal. The other important principle that GUI programmers will inevitably need to learn, earlier or later, is that appearance and logic must be kept as separate as possible. (Just ask anyone that has been programming active Web sites.) In our domain this means that we must drop the E from the DSEL and concentrate our efforts on supporting the use case where the GUI appearance is described by a _separate data file_ that is not embedded in the C++ code. We can afford to do that, because GUI building is not a performance-critical task. I have done GUI design in C++ code and believe me, it's a fundamentally flawed approach. ;-) The compile-link cycle can drive you mad. There are actually two Hello World programs, one that builds the GUI by hand and hence needs to map closely to the underlying architecture in order to 'teach' it by example, and another, that simply reads a GUI description from an external resource (XML is popular these days). We are trying to cram these two introductory programs into one. This is not needed, and can be harmful to both.