Code Monkey home page Code Monkey logo

elm-review-code-style's Introduction

elm-review-code-style

Provides elm-review rules to follow some of my personal code style preferences.

I tend to not have many rules related to code style thanks to using elm-format and Elm's simple language, and I think that elm-review brings more values by reporting different kinds of issues than code style infringements, but I do think that there are use-cases for it.

A few warnings before trying to add them to your review configuration.

  1. These rules enforce opinions I personally have on "nicer" Elm code, and honestly they're mostly about resolving things I find relatively annoying. Do not enforce the ones you or your team disagrees with in your project.

  2. These rules may be a source of more frustration (when the tests fails because of them) for your team and a source of work that will bring little value to your project. I try to provide fixes when I can to reduce that work though!

With that said, I recommend trying them out to help you decide.

Provided rules

Configuration

module ReviewConfig exposing (config)

import NoSimpleLetBody
import NoUnnecessaryTrailingUnderscore
import Review.Rule exposing (Rule)

config : List Rule
config =
    [ NoUnnecessaryTrailingUnderscore.rule
    , NoSimpleLetBody.rule
    ]

Try it out

You can try the example configuration above out by running the following command:

elm-review --template jfmengels/elm-review-code-style/example

elm-review-code-style's People

Contributors

jfmengels avatar lydell avatar martinsstewart avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

elm-review-code-style's Issues

NoSimpleLetBody should report destructuring for named patterns in other modules where destructuring does not change the type

At the moment, the rule doesn't report the destructuring of single variant constructors when we don't know whether the type has any phantom types (as that could be the purpose of the destructuring).

This correctly doesn't get reported.

type A b = A String
a = let (A b) = xyz
    in A b

But if the outer function has a type signature, and the return type is the same as the type of the value, then there is no need to destructure the value.

module A exposing (..)
type A b = A String

-- should be simplified
xyz : A String
xyz = -- ...

-- Can be simplified
a : A String
a n = let (A b) = xyz
    in A b

This probably needs type inference to work correctly.

NoSimpleLetBody should report destructured records patterns that are the same as the body

Example:

fn x =
    let
        { a, b } =
            value
    in
    { a = a, b = b }
-->
fn x =
    value

We can maybe push a bit further and simplify the following as well.

fn x =
    let
        result =
            value
    in
    { a = result.a, b = result.b }
-->
fn x =
    value

To work well, we need to know whether the set of keys in value are the exact same as the one in the return value. If value has a c field, then this destructuring means something. Type inference would help, but we can take a look at the function definitions, and ignore where we don't know well enough. If we can't infer the set of keys, we shouldn't report anything.

The order of the keys does NOT have to be the same, compared to tuples where the order does matter.

NoSimpleLetBody should report destructuring for named patterns where the type variable is not a phantom type

At the moment, the rule doesn't report the destructuring of single variant constructors when we don't know whether the type has any phantom types (as that could be the purpose of the destructuring).

This correctly doesn't get reported.

type A b = A String
a = let (A b) = xyz
    in A b

but the heuristic we use is to only check whether the type has type variables. We are not checking whether the type variable is actually a phantom one or not.

module A exposing (..)
type A b = A b
-- should be simplified
a = let (A b) = xyz
    in A b

There may some edge cases to figure out where this might be change things? For instance, what if the type is a phantom type by transition (used as a type variable to another type where it is a phantom type)? To be explored.

NoSimpleLetBody should report destructuring for named patterns in other modules

At the moment, the rule doesn't report the destructuring of single variant constructors when we don't know whether the type has any phantom types (as that could be the purpose of the destructuring).

This correctly doesn't get reported.

type A b = A String
a = let (A b) = xyz
    in A b

but we only gather information about constructors from the current module. If a single-variant custom type from another module or from a dependency is used in such a way when it doesn't have a phantom type variable, then we should report it.

module SomeModule exposing (A(..))
type A b = A String

-- other module
import SomeModule exposing (A(..))
-- should be simplified
a = let (A b) = xyz
    in A b

NoSimpleLetBody: Report functions

What the rule should do:

Report let functions that are defined as the partial application of a function, and only used directly in the body of the let expression.

What problems does it solve:

Unnecessary variable declarations

Example of things the rule would report:

fn value =
  let
    a =
      List.map fn
  in
  a data
-->
fn value =
  List.map fn data

Example of things the rule would not report:

The rule should only report when the value is a direct function call. It shouldn't report it when the function is more complex. Basically, we shouldn't have to add parentheses for this to work.

fn value =
  let
    a =
      if condition then
        List.map fn
      else
        identity
  in
  a data

If the function has arguments, we should not report it, even if it means the same thing

fn value =
  let
    a data_ =
      List.map fn data_
  in
  a data

If the function is referenced anywhere else in the let declarations or let body, then we should not apply this change.

I am looking for:

Someone to implement it

NoSimpleLetBody should not report errors for a variable that is referenced outside of the body

fn value =
  let
    a =
      something

    something =
      1
  in
  something
--> should NOT transform to
fn value =
  let
    a =
      something
  in
  1

The above should not be reported. Even though a is necessarily unused (at least for the current implementation), it may still exist for a bit, which will cause the code not to compile anymore. It's likely that NoUnused.Variables is enabled and will fix the issue anyway, but we shouldn't rely on this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.