Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPR#6709: document operators' associativity and precedence level #1167

Merged
merged 2 commits into from
May 14, 2017

Conversation

Octachron
Copy link
Member

Mantis:6709:
This PR proposes to document the associativity and precedence level of the infix operators defined in the Pervasives module. This information is redundant with the description of operators in the reference manual. However, such description is neither directly referenced in the Pervasives module and probably nor always fresh in the mind of potential readers.

I am also wondering if non-infix operators should be documented too, or if there are any natural name for the various precedence levels of infix operators.

Document the associativity and precedence level of pervasives
operators.
@dra27
Copy link
Member

dra27 commented May 11, 2017

For completeness, I'd add the precedence of (~-), (~+), (~-.) and (~+.) as it gives you the missing 1/9 case.

In all cases there should be a hyphen "Left-associative" and "Right-associative". I personally would say "at precedence level" or "with precedence level".

@Octachron
Copy link
Member Author

Thanks for the remarks, I have added the missing hyphens and replaced "with precedence level" by "at precedence level". However, I have left a gap in the precedence levels corresponding to the (#..) operator family (at precedence level 10/11). (Note that the first precedence level corresponds to := and was already cited in the previous version).

@dra27
Copy link
Member

dra27 commented May 14, 2017

Oh yes, I said 1/9 when I meant 9/9 before!

This looks great, thanks - squashing and merging...

@dra27 dra27 merged commit a8e770c into ocaml:trunk May 14, 2017
@gasche
Copy link
Member

gasche commented Oct 15, 2018

I was criticizing the current way precedence levels are described in the context of #2097, so I'm moving the discussion here.

I believe that "7/11" is not a very satisfying human-interface choice to describe the precedence of an operator. I am unable to tell what that means without looking at the manual, and the manual already gives me the precedence of the operator anyway, so the information as it is given is not very useful.

The associativity is fine, because it is specified in terms that humans can understand. The problem is with the precedence level. Here are things that I think would be better than saying n/11:

  • We could recall the precedence/associativity table in the .mli if we wish to.
  • We could assume that people have an intuitive understanding of the precedence of fairly-common operators (in particular mathematical operators), and define the operators starting with other infix symbols by relation to those.
  • We could give the position of the precedence level in the precedence order by showing an example at the level above and at the level below (and maybe another example at the same level).
  • We could make the precedence/associativity table in the manual easier to find, and just point to that one.

@Octachron
Copy link
Member Author

I agree that using simple ordinal is not really satisfying. However, it has the advantage of being both local (at the operator level), (pointlessly) precise and does not require a lot of setup. More precisely, among your suggestion

  • Recalling the table is not very local, and using row number in a local table in the operator description does not sound much better
  • No, I would not bet on any intuitive understanding of precedence beyond exponentation > multiplication > addition. Order relations like addition > logical and do not seem very intuitive to me.
  • Giving a representative of the precedence class sounds like a good idea. However, the information on the neighbors is very local: one need to scan the full list of operators to get an idea of the absolute position in term of precedence. One option might be to combine this local information with a more absolute position.
  • The precedence table should be easier to link with manual: a subsection for the precedence and associativity table #1837 .

Going on with you third suggestion, It might be easier to split the precedence table in subsections,

  • hash operators and non-binary operators
  • arithmetic (exponentiation/multiplication/addition)
  • generic (right/left)
  • logical (and/or)
  • assignment
    and add a copy of this table as an appendix to the pervasives module.
    Then, we could refer to the precedence using both this category and its relative position:

val (%)
.... is a left associative. Its has the same precedence as *., below ** and above + in the arithmetic precedence group .

with a link to the table.

@gasche
Copy link
Member

gasche commented Oct 15, 2018

Thanks for the reactivity! (And sorry about the somewhat negative tone of my previous comment...)

I'm not sure about splitting the table. I like having a single place to get a global view of precedence, and note that user-defined operators need not follow the semantic category used by standard-library operators in the same syntactic category. (Maybe seeing a rendered version of your suggestion could improve my feeling, but I'm not asking you to do that unless you yourself believe we should split that way.)

I like the idea of having a copy of the table within the standard-library documentation, so that we can easily (and robustly) hyperlink to it from the documentation.

I like your proposed document for (%), except for the "arithmetic precedence group" that doesn't really talk to me. Note that knowing the relative precedence across semantic groups is also important in practice (for example, abs @@ x + 1).

Thanks for providing a concrete example, it's easier to discuss with them.

@Octachron
Copy link
Member Author

Octachron commented Oct 15, 2018

You were perfectly right to criticize the current documentation. Rather than splitting the table, I was thinking of something like

Operators Associativity Group
**
*
+
left
left
left
Arithmetic
^
=
right
left
Generic

with Arithmetic, or Genericabstract syntactic category, but this is probably too complicated.

Another option might be to add references to the 4-nearest neighbors:

val (%)
.... is left associative. Its has the same precedence as *, below ** or unary - and above + or @

val (||)
.... is left associative. Its precedence is just above := , below &&, = and @ .

val (~-)
... . It has the same precedence as ! above unary - , **, * and + .

which has the advantage of reducing the diameter of the induced graph to 3.

@gasche
Copy link
Member

gasche commented Oct 15, 2018

I'm happy with the 4-nearest approach, although I can see how that might feel a bit cumbersome to contributors of new infix operators. Maybe making it slightly more work to add new infix operators is a feature...

@dbuenzli
Copy link
Contributor

I'm not convinced by the nearest approach, the only think that is going to be ever clear is the actual table and I think reproducing it in the api docs and link to it from each operator would be the best.

@Octachron
Copy link
Member Author

I was thinking of having both a link to the actual table and references to the neighboring precedence classes. Do you think that the neighboring classes are too noisy?

@dbuenzli
Copy link
Contributor

dbuenzli commented Oct 15, 2018

Do you think that the neighboring classes are too noisy?

Maybe speaking in terms of classes may help actually. The 4-nearest neighbours did however feel noisy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants