problem-solving
problem-solving copied to clipboard
Operator precedence/associativity API needed
Rakudo currently exposes operator precedence and associativity info through Code's prec method. Being able to introspect into precedence and associativity is very helpful. However, @jnthn brought up some good reasons not to stabilize that API:
There should be a way to introspect these things, but I'd not support specifying
prec, as:1. I don't think a hash is the right thing to return here. (It raises all kinds of questions. Like, can you mutate the hash to change the precedence? :-)) 2. It's a bit odd that getting the precedence level is `.prec<prec>`. We're using the word to mean everything related to precedence _and_ to the level.
See rakudo/rakudo#4776. Accordingly, I'm opening this PR to solicit people's views on what API we should stabilize. A few questions to get us started, (I'll post my own views on the below separately).
Do we want to
- …expose this API on all Code or just operators?
- …include just precedence and associativity, or also other related values (e.g.,
thunky,iffy,diffy,fiddly)? - …commit to/spec an exhaustive list of properties or a current (but extensible) set?
- …expose the internal values or a human-readable version? Or both? (e.g., for precedence,
t@=ortighter than &infix:<+>) - …expose (and thus spec) the names of various precedence categories used internally (the ones currently listed in the operator precedence table)? This might make the example above
tighter than additiveinstead. - …have this be a read-only API or do we want to use it for mutation as well? If so, just at compile time, or also at runtime (what would that mean)?
- …deprecate the existing .prec API (though maybe that's a Rakudo question rather than one for this repo)
Additional thoughts are very welcome :)
@jnthn finished the comment I quoted above by saying:
A further design issue in Rakudo today is that operator precedence properties are duplicated in multiple places: in the grammar and then also for introspection via
.prec. That's not really ideal. In therakuastbranch (work thanks to @lizmat) there is anOperatorPropertiesobject, along with some shortcut methods that delegate to it. I think that would be a better API to spec.
I haven't familiarized myself with the rakuast branch yet, but I took a look at operator-properties.rakumod and I agree that it looks like a great foundation for a spec-ed API.
Here are my own views on the questions I posed above (though I'm open to persuasion on any, of course).
expose this API on all Code or just operators?
"all Code objects". Non-operators may all have the same precedence/etc., but it seems nice to be able to see what that is anyway. However (warning: bikeshedding) that raises the question of whether "OperatorProperties" is really the right name for these objects…
include just precedence and associativity, or also other related values (e.g.,
thunky,iffy,diffy,fiddly)?
I lean towards "all", but I'm not sure I entirely know the effect of all of those properties. (But maybe that's part of why I lean towards "all" – once they're spec'ed, we can doc them).
commit to/spec an exhaustive list of properties or a current (but extensible) set?
"an extensible set", imo. I think we're currently using "associativity" to capture something about arity (see rakudo/rakudo#4779) and I think the best solution to that is to add a new operator property. Even assuming that's added before we spec this API, I wouldn't want to commit to us having thought of everything.
expose the internal values or a human-readable version? Or both? (e.g., for precedence,
t@=ortighter than &infix:<+>)
My preference would be for "both", but via some sort of lightweight wrapper class that could .gist to one value and .raku to another.
expose (and thus spec) the names of various precedence categories used internally (the ones currently listed in the operator precedence table)? This might make the example above
tighter than additiveinstead.
I'd like to see these categories spec'ed regardless, and this seems like a good chance to do so. Right now, they're in an awkward grey area: they're mentioned in the Synopses and in the docs, but not in Roast and they're not really documented (just mentioned on the operators page).
have this be a read-only API or do we want to use it for mutation as well? If so, just at compile time, or also at runtime (what would that mean)?
I'd say "read-only", but handle compile-time OperatorProperty modification happen by creating a new OperatorProperty (or whatever we call it) object. I don't think runtime mutation of OperatorProperty objects makes sense (though of course there are various ways to nest a compile time inside runtime, which would have much the same effect).
deprecate the existing .prec API (though maybe that's a Rakudo question rather than one for this repo)
We can probably deprecate it unless it's needed for some reason I'm not aware of.