[m-rev.] for review: delete see/seen/tell/told from io.m

Julien Fischer jfischer at opturion.com
Sat Mar 5 18:51:20 AEDT 2022


Hi Zoltan,

On Sat, 5 Mar 2022, Zoltan Somogyi wrote:

> 2022-03-05 17:05 GMT+11:00 "Julien Fischer" <jfischer at opturion.com>:
>
>>>> Set D: I think we should move the predicates that read and write bitmaps
>>>> to bitmap.m.
>>>> PROPOSAL: move the code to bitmap.m now
>>>> PROPOSAL (from julien): move the code to write arrays to array.m now; agreed
>>>> PROPOSAL: leave io.write_list in io.m for now
>>>
>>> Ok to all three.
>>
>> Leaving io.write_list in the io module while the corresponding write
>> predicates for other data types are moved to their respective modules
>> is inconsistent.
>
> The thing is that io.write_list is quite different from other output predicates,
> because its main job is not writing out the list (list.foldl(io.write) on the list
> will do that just fine), but managing what goes *between* the elements.

Its behaviour is similar io.write_array, which according to the above
*is* being moved.

> I think its true replacement would be a new version of list.foldl that
> allowed the specification of actions to be done between elements,
> including probably versions that allow the specification of a different
> action for the gap between the last two elements. (By action I mean
> an update to the accumulator(s).)
>
> This is why I proposed leaving it *for now*.s

I'm fine with leaving it for now; given how long it is has been present
in the io module we won't be removing it anytime soon anyway.

> An issue just came up when I moved the code for reading/writing
> bitmaps to bitmap.m: where should we keep the various  instances of typeclasses
> such as stream.bulk_reader and stream.writer that say how to read/write
> non-primitive types? Specifically, if the reading/writing code for that type
> has been moved to another module, should the instance declarations
> go with them, or should they stay in io.m?
>
> I can see arguments in favor of both answers. Logically, an instance that
> implements a typeclass method using a predicate should be in the module
> that defines that predicate. OTOH, this may require modules to import
> the modules that define the typeclasses just for the sake of the instance
> declaration, and it makes checking whether a class has an instance for
> a given type harder.

Since those instances are for types (i.e. io.state and bitmap) from both
modules, they could be resasonably declared in either.

On balance, I favour moving them to bitmap.m.

>>>> Set K: We could move the predicates operating in the globals to a new
>>>> module globals.m, if we didn't mind the name clash with compiler/globals.m.
>>>> PROPOSAL: move them to io.globals.m now
>>>
>>> PROPOSAL: deprecate and remove them
>>
>> As Peter mentioned further in this thread, the the role of io.globals is
>> now (mostly) subsumed by mutables.  The latter are usually better anyway
>> as they don't require packing things inside a univ.
>>
>> The one place where io.globals provides functionality that mutables do
>> not is allowing atomic updates, via io.update_globals/3. It was always
>> intended that mutables be extended to support that as well; once that
>> exists I think we can deprecate and (eventually) remove the io globals.
>
> In fact, I just replaced the only code left in the Mercury system that used
> the globals in the I/O state: profiler/globals.m. I replaced it with a mutable
> attached to the I/O state. Updates to mutables done via the I/O state
> should be as atomic as updates to the globals.

Updating a mutable's value may well be atomic, however update_globals/3
does a bit more.  Specifically, it does the following:

     1. Gets the current value in the globals.
     2. Applies a closure that transforms it in some way.
     3. Sets the value of the globals to the transformed value.

All of that is supposed to be atomic; AFAIK nothing in the currently
documented mutable implementation allows for that.

Julien.


More information about the reviews mailing list