[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Comments on SRFI-39



At Sun, 26 Jan 2003 03:45:50 -0500, shivers@xxxxxxxxxxxxx wrote:
> Matthew asked "Why mutable params?" I support them, with the *exact* semantics
> Marc provides -- threads *inherit* the dynamic bindings. This allows thread
> code to be written that interacts w/other threads via shared state accessed
> from a parameter. The agent that forks off the threads controls the degree of
> sharing or insulation by arranging sharing of parameter cells.

FWIW, PLT is currently exploring making all built-in parameters
immutable.

The problem is that mutable parameters make the library writer's life
too difficult. I think you've actually made a good argument for this
claim near the end...

> For example, consider a cursor-like object, such as a "current working
> directory" or a pointer into a database table. Two threads might want to
> move around in the directory structure or the table by altering the cursor.
> One thread changes the cursor, the other sees it. You arrange this by
> (1) binding the param to a fresh cell, then (2) spawning two threads in the
> single dynamic scope of that binding.

In this relatively unusual situation, use a mutable value instead.

I say it's unusual. Here's the common case: a library function wants to
use a filename multipe times, and the filename happens to be relative,
so that it's resolved with respect to `current-directory' each time
it's used. The library function wil do somthing strange if
`current-directory' changes its value half-way through.

The library can protect itself by resolving the filename once, but
that's a pain and it's difficult to remember to use that pattern every
time.

[BTW, in Windows, the OS's current-directory is process-specific (as in
most OSes), not thread-specific. Furthermore, certain built-in dialogs
modify the current-directory setting. The end result is that the
OS-level currect-directory setting is useless to MzScheme, because a
dialog might change its value at any time. Indeed, there's at least one
unrelsolvable race condition where MzScheme must set the OS-level
current directory before performing an exec(), and there's no way to
block active dialogs before the exec() takes place.]

> Suppose, however, you want *independent* thread groups. No trouble there, 
> either. You just spawn each thread or cooperating thread group in a
> different dynamic-parameter binding.

I note that you'd have to predict in advance which parameters will be
used among the threads, or you need a "create a fresh binding every
parameter" primitive. The latter is reasonable.

> I readily admit you can implement mutable params with immutable params and a
> one-elt vector. But I also buy Marc's story that this is not "the way of
> Scheme" -- you could also "implement" mutable *variables* with immutable vars
> & one-elt vectors, but Scheme doesn't. Also, if you emulate mutable params
> with immutable params + mutable cells, you *expose the cell to parameter
> clients* -- when you just want to expose the *value of the cell*. This can
> lead to bugs, in the general way bugs happen when you expose the underlying
> encoding of a thing (e.g., you encode a structure as a three-element list or
> something like that). Providing mutable params as a primitive locks up the
> internal cell so buggy clients can't accidentally fetch it out, store it away,
> pass it around, reference it outside of scope, etc.

Doesn't the same thing happens with mutable parameters? If you want to
grab the current binding, just grab the continuation.

> Sound like an abstract objection? It's pretty concrete, actually, by which I
> mean that it's not an unrealistic bug -- it's the kind of bug you would expect
> to see in real code.

I absolutely agree, and I think the same sort of bugs happen when
threads share mutable bindings.

Matthew