Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote in article
<3364DD2D.86195F2@physik.tu-muenchen.de>...
> John Ousterhout wrote:
>
> [...]
>
> > >The button example requires about 25 lines of code in three procedures
> > >when implemented in C++ with Microsoft Foundation Classes. Just
> > >setting the font requires 7 lines of code ...
> >
> > Come on! All this shows is the inconveniece of using the MFC
> > classes. An interface exactly the same as the Tcl one could easily be
> > written in C++.
> >
> > I invite anyone who believes this to try to do it, and post the results.
> > I've had this argument before, and when people do this, one of two things
> > happens: either they eventually concede that this is hard to do in C++, or
> > they define new C++ APIs that are essentially untyped (e.g. they use
> > strings for everything). This just supports my arguments that types get
> > in the way of gluing. You can build untyped APIs in strongly typed
> > languages, but they tend to be clumsy because the languages are designed
> > to encourage strong typing. If you need an untyped approach, you might
> > as well use a language designed for that.
>
> Well, I found this discussion just now, but this is IMHO easy to answer:
>
> void action() { cout << "Hello" << endl; }
>
> button b=buttonstyle().text("Hello").font("Times",16).execute(action);
Indeed! I have written such a C++ GUI toolkit myself. I started writing it
because I found MFC and Borland's OWL to be so useless. Because I'm a Tcl/Tk
programmer, I used Tk's model of layout managers and configurable GUI
components.
E.g, here's how a main window with some buttons would be created, first in Tk:
proc Quit { ... }
proc Beep { ... }
proc MyMainWindow {w} {
toplevel $w
wm title $w "An Example Main Window in Tk"
# Create and configure user-interface widgets
#
button $w.quit -text "Quit" -command Quit
button $w.beep -text "Beep" -command Beep
# Layout widgets
#
grid $w.quit -row 0 -column 0 -sticky nsew
grid $w.beep -row 0 -column 1 -sticky nsew
}
And now in my framework, WOOL. This is a little larger, but is more
explicit about the relationship between components:
#include <mainwin.h>
#include <button.h>
#include <action.h>
class MyMainWindow : public MainWindow
{
private:
void quit(); // Closes the main window and quits the application
void beep(); // Makes a beep noise - just an example
GridLayout _grid; // Layout manager
TextButton _quit, _beep; // GUI components
public:
MyMainWindow( HINSTANCE app ) :
MainWindow(app,"An Example Main Window in the WOOL libary"),
_quit(this), _beep(this)
{
/* Configure the user-interface widgets
*/
_quit.text("Quit")
.action(new
MemberAction<MyMainWindow>(&MyMainWindow::quit))
_quit.text("Beep")
.action(new
MemberAction<MyMainWindow>(&MyMainWindow::beep))
/* The grid layout manager will fill the window, allocating the
* space to its slaves
*/
this->manage(_grid);
/* Tell the layout manager which slaves to layout and where to
* to put them.
*/
_grid.manage(_quit).row(0).column(1).anchor(fill);
_grid.manage(_beep).row(0).column(0).anchor(fill);
}
};
And using C++ has a number of other advantages. Because the interactions
between layout managers and layout slaves are defined in terms of abstract
interfaces, a layout manager can lay out any object which provides the
LayoutSlave interface and so can lay out Widgets, canvas objects and even
other layout managers. The latter is useful because it reduces the need
for extra frame widgets which only exist to create pleasing layouts.
I haven't found the need to use weak typing, probably because I make
full use of C++'s template mechanisms, and because I find it natural
to design frameworks in terms of roles and interactions defined using
strongly-typed abstract interfaces. I also designed the framework to
interact with other frameworks by providing interfaces through which
event loops can be merged and support for multiple threads.
There is nothing in C++, strongly typed languages or object orientation
which makes it impossible to glue components together or implement reusable
software components. Its just that you have to design things that way
from the start. It is exactly the same with Tcl/Tk. It is as possible to
design an infexible and un-reusable component for Tcl/Tk as it is for
C++ or any language. It's not a platform or language issue, but a
design issue.
IMHO, The flaw in Dr. Ousterhout's paper is that it can essentially be
boiled down to the argument "A well designed framework is better than a
poorly designed framework" with which nobody can argue but which says
nothing about the usefulness of Tcl or scripting languages in general.
Cheers,
Nat.
--
+-------------------------------------------+---------------------------------+
| Name: Nat Pryce MEng ACGI O- | Mail: Department of Computing, |
| Email: np2@doc.ic.ac.uk | Imperial College, |
| Tel: +44 (0)171 594 8394 (Direct Dial) | 180 Queen's Gate, |
| Fax: +44 (0)171 581 8024 | London SW7 2BZ, |
| WWW: http://www-dse.doc.ic.ac.uk/~np2 | United Kingdom |
+-------------------------------------------+---------------------------------+
|