Skip to main content
Add a second linter to the set
Source Link

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, which do more work looking for possible errors than compilers or interpreters, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default, while PC-Lint Plus has a variety of lint messages relating to operator precedence, like messages 514, 9050 and 9113.

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, which do more work looking for possible errors than compilers or interpreters, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default.

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, which do more work looking for possible errors than compilers or interpreters, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default, while PC-Lint Plus has a variety of lint messages relating to operator precedence, like messages 514, 9050 and 9113.

Clarify what I meant by the linters paragraph.
Source Link

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, on the other handwhich do more work looking for possible errors than compilers or interpreters, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default.

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, on the other hand, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default.

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, which do more work looking for possible errors than compilers or interpreters, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default.

Source Link

It makes implementation easier.

You would simplify implementation if you had no precedence or associativity rules at all; but once you've implemented handling of PEMDAS, adding more operators to the precedence and associativity rules is simple; it's two more pieces of data to attach to the operator (precedence level, and left/right associative). Indeed, in Haskell, you can define precedence and associativity for user-defined operators.

Erroring, on the other hand, is extra code; you have to detect that this is a case that would be ambiguous (you don't want an error for a << b, even if you do want one for a << b + c), then determine that you don't have a precedence and associativity to choose, then output a decent error.

Linters, on the other hand, often do warn you when it's potentially unclear; for example Rust's Clippy linter has a warn-by-default lint for unclear precedence, and a separate one for unclear bitwise masking that's allow-by-default.