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

Zoltan Somogyi zoltan.somogyi at runbox.com
Sat Mar 5 17:40:18 AEDT 2022


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.

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*.

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.

>>> >> Set I: We should move the predicates handling environment vars to
>>> environment.m, as discussed.
>>> PROPOSAL: move them to io.environment.m now
>>
>> I'm neutral on this. Could just leave them in io.m like progname and
>> command_line_args.
> 
> I support moving environment handling to a separate submodule.
> At the very least, the existence of io.environment should make it more
> obvious to users where the envionment handling predicates live.

OK, it looks like two in favor with one abstention.

>>> 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. If you are worried about
impure, non-I/O updates to the mutable, then we should add a way
to ask for mutables that can *only* be accessed via the I/O state.
This would be an attribute that is incompatible with attach_to_io_state
(and with constant and trailed). What should be its name?
access_only_via_io_state, perhaps?

Zoltan.


More information about the reviews mailing list