event-oriented programming

In event-driven programming, also termed event-based programming or event-oriented programming, events are central to the flow of the program.

Description

Although similar in some ways to the idea of concurrency, event-driven programming is a strategy for designing the control flow of a program which must react to events that are external to the program itself. Such programs may use threads, coroutines, continuations, generators, and other facilities to accomplish the goal of processing external events.

Events play a more prominent role in Tcl than in many programming languages, with commands such as after, fileevent, and vwait providing the interface. Even before Tcl had a native event loop, Tk commands such as bind and event provided event-processing faciltities for Tk.

Events are a relatively "safe" programming model, particularly when compared to threading.

John Ousterhout's influential Why Threads Are A Bad Idea presented events as an alternative to threads, since an event loop works in a single process, with no concurrency involved.

Examples

Driving tclsh with Expect
includes an event-driven version of a script to feed a Tcl script into an interactive tclsh

Commands

Tcl commands relevant to event-driven programming

after
update
vwait
fileevent

Tk commands relevant to event-driven programming

bind
event

See Also

event loop
an introduction to event loops
Event Processing
Tcl event loop
a description of the Tcl event loop in particular
Event programming and why it is relevant to Tcl/Tk programming
Threads vs. events
event
the Tk command
uevent
Tcl only user events similar to Tk's event
efr-lib
a set of Tcl libraries (formerly called TIL) contains event module that is similar to Tk event
wiki search: "event"
Windowing system events
Catching window managed events
virtual event
Event generation has limits
Mixing Tcl/Tk and Xt Event Loops

Reference

Event-Driven Programming: Introduction, Tutorial, History"
a SourceForge project by Steve Ferg to collect information about event-driven programming
Event-Driven Programming, c2.com

Misc

Notice that C# makes events first-class objects. This is consistent with Anders Hejlsberg's earlier work with Delphi ...


Martin Lemburg 2002-07-11:

I have a question:

Why isn't there an "Invoke" event for invokeable widgets like buttons? Wouldn't it make sense to have such an event? To bind widgets using the Invoke event, like to connect a widget with the -command option to an event handler?

Then ...

button .b -text exit -command {cmdProc .b [clock seconds]};

... would be equal to ...

bind .b <Invoke> {cmdProc %W %t};

It shouldn't be a problem to use the substitution capabilities during the usage of a binding, like:

button .b -text exit -command {cmdProc %W %t};

Wouldn't that be nice and consequent? Wouldn't it be consequent (for example) to use bindings to scrollbars or entries too? ...

entry     .e   -textvariable filter;
button    .b   -text "filter";
listbox   .lb  -listvar data -selectmode extended;
scrollbar .sbx -orient horizontal;
scrollbar .sby -orient vertical;

bind .e   <Validate> {validateFilter %V %s};
bind .b   <Invoke>   {filter .e .lb};
bind .lb  <XScroll>  {.sbx set};
bind .lb  <YScroll>  {.sby set};
bind .sbx <Invoke>   {.lb xview};
bind .sby <Invoke>   {.lb yview};

There would be the chance to elimate all (event)handlers from that code, that only builds up the GUI. The code to handle events could use now use bindings.


While Tcl-ers are generally trained to believe, "event orientation: good; threads: bad", that is, of course, an exceptionally truncated version of reality. Threading's programmability problems begin with the necessity to mess with data consistency. Event-based programming, on the other hand, needs continuations or closures or comparable expressive power to manage the program-control stack. With none of these, developers must mess with stack contents on their own, and, of course, that's a horror.

WK: Threads used for everything are a bad thing. I think that Tcl community is getting to like threads, but I like the idea that I can have every single interaction (GUI and network) in one thread and if I need some long lasting calculations, I can just add a thread and communicate with it using thread::send -async, and then (well a small nice wrapper is a must here :-) I can talk to a thread similar to a networked application. And it takes 30 lines to wrap this:

set code [catch $someCommandList result]
myCallback $code $result

into

asyncEval $someCommandList myCallback

And this is how larger calculations could be done easily.

Tcl performs its usual compromise and provides everything as a string. More precisely, Tcl gives enough introspection to pack and unpack events and their "formal arguments". That's enough.