julia-vscode / StaticLint.jl

Static Code Analysis for Julia
Other
145 stars 28 forks source link

Require parentheses for ambiguous operator pairings #299

Open jtrakk opened 3 years ago

jtrakk commented 3 years ago

Given

df = DataFrame(a=[1,2,3])

then

transform(df, :a => x->x => :b)

is

transform(df, :a => x -> (x => :b))

not the desired

transform(df, :a => (x -> x) => :b)

so it creates

3×2 DataFrame
 Row │ a      a_function    
     │ Int64  Pair…         
─────┼──────────────────────
   1 │     1  [1, 2, 3]=>:b
   2 │     2  [1, 2, 3]=>:b
   3 │     3  [1, 2, 3]=>:b

not the desired

3×2 DataFrame
 Row │ a      b     
     │ Int64  Int64 
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

I accidentally did this just now and it was hard to debug.

In Guy Steele's JuliaCon talk he argues that most operators shouldn't have fixed precedence rules because it's too easy to make mistakes. "We use only the most obvious and familiar rules of precedence" and use parentheses to disambiguate otherwise. "Our motto was, if you didn't learn it by first year college, you shouldn't be relying on it."

@StefanKarpinski said

I believe that Fortress supported non-linear operator precedence, which strikes me as a step too far and quite confusing. However it might make sense for Julia 2.0 to require disambiguation for some pairs of operators, requiring explicit choice of precedence when the relative precedence is non-obvious. There would, however, still be a linear precedence ordering. Of course, you could just declare some operator to have ambiguous precedence relative to all other operators and it would effectively be unordered, but that seems quite annoying.

Requiring paretheses for some pairs of operators would extend Julia's helpful practice of raising errors for some ambiguous parses.

Before 2.0, these checks could be lints.

I'm not sure how to create a list of unambiguous operator pairs.

davidanthoff commented 3 years ago

I wouldn't want that as a default, but could imagine a config option to enable something like that.