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

Rule for List.length l = 1 and l.Length = 1 #543

Open
smoothdeveloper opened this issue Apr 19, 2022 · 2 comments
Open

Rule for List.length l = 1 and l.Length = 1 #543

smoothdeveloper opened this issue Apr 19, 2022 · 2 comments

Comments

@smoothdeveloper
Copy link
Contributor

smoothdeveloper commented Apr 19, 2022

Taking a discussion running on dotnet/fsharp#12998 (comment) related to replacing list.Length = 1 with cheaper construct.

@smoothdeveloper: Wondering if this wouldn't be worth a rule in FSharpLint?
@knocte : Good idea, although it would be much easier to make the violators of the rule respect it if there was an isSingleton function in FSharp's List, shouldn't we add that function first?

@knocte I don't know the inner philosophy of FSharpLint, if I had to split it the way your question suggests:

  • law is the law, it is applicable, but not ideal, the resulting code is not as good as if you defined your own abstraction (List.isSingleton here), what matters is, helps the developer to save CPU cycles, more than how the code is changed
  • the law is only mostly applicable if it becomes path of least resistance, least surprise, most sense, to most, and increasing likelyhood of "code I love" ratings from @dsyme is what matters

First one is like mechanic empathy, the second one is developer empathy, and FSharpLint is probably helping setting good balance where it makes most sense (those easy cases).

I'd say considering the discussion stems from an internal compiler member for now, chance of the fix making it to FSharp.Core soon are not the most favorable, for delaying having the check, for those looking to refactor the code already (they can introduce type extension for it manually), if the check can be added without a lot of work.

We can suggest = [] ... edit. not! we can only suggest to have the module extension, which kind of answers the question.

I'd just like to have this warning or the FCS analyser thing, to be running mostly, and fixing the code is exercise left to the reader.

cc: @auduchinok

@knocte
Copy link
Collaborator

knocte commented Apr 20, 2022

@smoothdeveloper thanks for filing this bug.

I just became recently a maintainer so take my PoV with a grain of salt (and don't assume I know the "inner philosophy" of FSharpLint in its entirety :) ).

My suggestion to add List.isSingleton to FSharp.Core's List was, essentially, because without it:
a) A rule for this would need slightly more complicated documentation to guide the FSharpLint user to respect the rule.
b) The above, combined with the slight ugliness of the solution, would not really motivate me to write such a rule :-P (yet?).

But if you have the time to write it, sure, please propose a PR, even if List.isSingleton is not included yet in FSharp.Core.

Side-note: maybe a suggestion that is easier to be merged in the short-term is to actually propose a PR for FSharpx.Collections (in fact we did something similar recently and now FSharpLint suggests FSharpx.Collections in another rule), before it gets proposed/merged in FSharp.Core.

@abelbraaksma
Copy link
Member

abelbraaksma commented Jun 22, 2022

Just my 2p:

Adding the following to the hints section will give you a Lint error. The replacement code is sound and exists in FSharp.Core, though not ideal, List.isSingleton may be better. But anybody seeing this error may just write such a function and fixes the rule. Using |> failed to be parsed by FSharpLint, hence the >>-approach.

"(List.length x) = 1 ===> (List.tryExactlyOne >> Option.isSome) x",
or:
"(Seq.length x) = 1 ===> Option.isSome <| Seq.tryExactlyOne x",

PS, a little bug in FSharpLint doesn't repeat the x of the hint (2nd option above doesn't have this bug):

FL0065 (List.length x) = 1 might be able to be refactored into (List.tryExactlyOne >> Option.isSome).

An alternative would be to add List.hasLength to FSharp.Core, which allows short-cutting List.length x = y.

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

No branches or pull requests

3 participants