[m-rev.] for review: convert parse trees to strings
Julien Fischer
jfischer at opturion.com
Wed Nov 1 16:08:49 AEDT 2023
On Tue, 31 Oct 2023, Zoltan Somogyi wrote:
> The diff adds the typeclass constraint "pt_output(S, U)"
> to many predicates in the compiler. To avoid losing efficiency,
> we want to created versions of those predicates specialized
> to their current use case (where S is an output stream,
> and U is the I/O state), and their intended new use case
> (where U is string.builder.state, and S is the corresponding handle).
>
> Unfortunately, adding two type_spec pragmas to every predicate
> with that constraint has two problems. First, it is tedious, and
> second, if any predicate is missed either now or later as new
> predicates are added, we lose the benefit of specialization
> in the affected part of the call tree. (This is already an issue
> in files such as library/term_io.m.)
This kind of what we might call templatey specialisation is an issue
beyond the compiler, see for example my mercury_json library.
> I therefore propose a new pragma that asks for the specialization
> of all predicates and functions in a module that have a specified
> typeclass constraint. The intended two examples would be
>
> :- pragma type_spec_constrained_preds(pt_output(S, U),
> [S = io.text_output_stream, U = io.state]).
> :- pragma type_spec_constrained_preds(pt_output(S, U),
> [S = string.builder.handle, U = string.builder.state]).
No objection from me, other than perhaps the name. For that
I suggest type_constraint_spec.
> The internal representation of this pragma would record the name
> of the module in which the pragma appears. (This would happen regardless
> of whether it appears in a .m or in a .intN file.) The compiler would
> then apply the type specialization described by the second arg
> to all predicates and functions in that module that have the
> type constraint in the first arg.
So it only applies to a single module?
> That typeclass constraint would be required to have the form of
> a typeclass name applied to one or more type variables. There are two ways
> we could go on how we determine which predicates and functions have that
> type constraint. The typeclass name would obviously have to match,
> but we could either
>
> - require that the names of the type variables match as well, or
> - apply type specification regardless of whether the names of the
> type variables match.
>
> I plan to do whichever of these the current code for type_spec pragmas does,
> because
>
> - consistency is important,
> - whatever the current code does has obviously worked well enough, and
> - it would be easier to implement :-)
For the sake of robustness, I suggest doing the second. Users may have
perfectly valid reasons for renaming the type variables on the constraints
on predicates or functions.
> I do intend to *find out* which of the two options above the current
> code implements, and explicitly document that choice for both the old
> and new pragmas.
>
> The syntax of the second argument above intentionally differs from
> the syntax of the existing pragma. The syntax of the type_spec pragma
> accepts two kinds of substitution specifications. One is a substitution
> for a single type variable, like this:
>
> :- pragma type_spec(pred(subset/2), T = var(_)).
>
> The other is for a substitution for two or more type variables, like this:
>
> :- pragma type_spec(pred(format_quoted_char/4),
> (Stream = string.builder.handle, State = string.builder.state)).
>
> Basically, if you want to specify a substitution for more than one variable,
> you have to put parentheses around their conjunction.
>
> I think putting all the variable substitutions in a list, regardless
> of whether there is only one or not, is simpler, which is why the new
> pragma examples above use that syntax. My preferred course of action
> would be to
>
> - implement the new pragma with the syntax requiring all substitutions
> be in a list,
>
> - change the implementation of the old type_spec pragma to *allow*
> all substitutions being in a list, and then
>
> - recommend that people use the new syntax from now on.
Agreed. The list syntax is also consistent with the vast majority of
other pragmas in the language.
> We *could* deprecate and eventually stop supporting the old syntax,
We should deprecate and eventually stop supporting it. (But it doesn't
have to be soon.)
> but I don' see much to be gained by that course of action.
- not having to maintain the code that supports to the old syntax.
- potentially not confusing users, by having two syntaxes.
Julien.
More information about the reviews
mailing list