T.R | Title | User | Personal Name | Date | Lines |
---|
1205.1 | Are you already using your callback closures? | DECWIN::KLEIN | | Mon Jul 31 1989 16:38 | 6 |
| Why aren't you passing the address of the data structure as the "closure"
to the callback routines? If using UIL, try using a UIL identifier to
point to the data structure.
-steve-
|
1205.2 | some ideas... | R2ME2::OBRYAN | When in doubt, let the user decide. | Mon Jul 31 1989 16:45 | 28 |
|
> I am creating an application in which I collect lots of little pieces of
> information. From these pieces I am assembling a data structure
> that I eventually process. Each piece of information is collected from
> a different DecWindows object. The only solution I have found so far
> is to define a pointer to the data structure globally, and then have
> each callback routine add to the global data structure as a side effect
> of being called. This works OK, but I'm wondering if there is some
> better way of doing it.
Here are a couple of ideas (not necessarily better):
1. Use the 'user data' field (which all widgets possess) of each
widget. When you are preparing to create your toplevel widget,
allocate memory for your special data structure, then use the
address as the value of the user data field for each widget you create.
(When using the toolkit directly, this means supplying the value
via the low-level create. If using UIL/DRM, you can use a UIL
identifier to get the same effect.) On each callback, whenever you
need to set a widget-related value, GetValues the user data field.
(I'm told that GetValuing the user data field is costly time-wise.)
2. Instead of using the user-data field to hold the address of your
data structure, use the callback tag in each widget in your interface.
(This can be achieved by specifying the address when building the
callback list, or (in UIL/DRM) using identifiers.)
There are undoubtedly thousands of others.
|
1205.3 | | FLUME::dike | | Mon Jul 31 1989 18:11 | 9 |
| Not all widgets have user_data fields. All widgets subclassed from
Common do, but SText isn't, and doesn't have user_data, at least the
last time I checked. This is the best method I have found so far.
You still need a piece of global data for the duration of the
FetchWidget call to initialize the user_data fields, but that is not
too bad.
Jeff
|
1205.4 | Ah, nope. Got none o' those. | EPIK::BUEHLER | Nertz! Profligate Nertz! | Tue Aug 01 1989 01:53 | 7 |
| Where did the term 'closure' come from? I don't ever recall seeing it
in print, nor did I learn such a term in my CS studies. I understand
the concept, ramifications of having/not having, etc, but I just wonder
where it came from.
John
|
1205.5 | | CASEE::LACROIX | Object oriented dog food? No, sorry | Tue Aug 01 1989 04:51 | 8 |
| > Not all widgets have user_data fields. All widgets subclassed from
> Common do, but SText isn't, and doesn't have user_data, at least the
> last time I checked.
Fixed for V2.
Denis.
|
1205.6 | | KOBAL::VANNOY | Jake VanNoy | Tue Aug 01 1989 10:09 | 4 |
| > Where did the term 'closure' come from?
It's a Charles Haynes-ism. He told me it comes from LISP usage.
|
1205.7 | Thanks... | ISE005::ROGERS | | Tue Aug 01 1989 13:24 | 14 |
|
Thanks for the quick responses. I should have prefaced my question by
pointing out that I am a novice DecWindows user, and am (so far) working
without having had any sort of overview instruction. Any suggestions,
no matter how obvious they may seem to you, are welcome. I'll explore
both suggestions (closure and user_data). I'm glad someone else found
the 'closure' terminology obscure! I am still a little unclear about it.
Is the closure field just a field available to the user? Any more info
out there on the derivation?
Thanks again.
Brenda
|
1205.8 | LISP closures -- I don't see the relationship to toolkit... | AITG::WELLS | Unmatched parenthesis | Thu Aug 03 1989 15:09 | 43 |
| In LISP a closure is the combination of a function definition and an
environment describing the references in the definition. The word
comes from the notion of a variable reference being "closed over" a
scope. For example:
(let ((x 0))
(defun integers ()
(setq x (1+ x))
x))
In this case the definition of the function INTEGERS takes place inside
an environment where X is bound to 0. When there is a call to INTEGERS
the bound value of X is incremented and returned. A call to the
function modifies the environment of the closure directly, so
subsequent calls will return successive integers.
Another way this could be achieved is:
(defvar x 0)
(defun integers ()
(setq x (1+ x))
x)
This however is *not* a closure because INTEGERS is defined in the
"null lexical environment" (i.e. nothing is bound lexically around the
definition of INTEGERS).
Although at first glance it seems like these are really identical and
both use global state the first case really doesn't, because only those
function defined in the same lexical environment as INTEGERS (in this
case none) can access that particular value of X. In the second case X
is truly a global variable that can be modified by any other function.
However, using closures is not at all the same as argument passing,
because this "locally global" state stored in the environment is
preserved for subsequent calls to the functions, i.e. in a
multi-threading world you could lose if you tried to use the closure
storage for values that are supposed to be unique per thread.
Richard
|