jamesjwood/purescript-coding-standard icon
public
Published on 3/14/2025
jamesjwood/purescript-coding-standard

Purescript coding standard

Rules

Coding Standard

  • use newtype instead of type where possible
    • type is a type synonym, which is a weak form of newtype
    • newtype is a strong form of type that allows for more type safety
  • prefer using newtype over data for single-variant types
    • data is designed for multi-variant types
    • data introduces a runtime overhead of boxing and unboxing
  • prefer using records over anonymous tuples
  • use do only in monadic context, use where or let otherwise
    • using do in non-monadic context is misleading and confusing
  • use record-destructuring pattern matching over case-expression pattern matching where possible
    • record-destructuring pattern matching is more concise and readable, use it when possible
    • case-expression pattern matching is more flexible and powerful, use it when necessary
  • prefer using full nouns for identifiers instead of abbreviations
    • examples
      • correct: state
      • wrong: st
      • exception: extremely long identifiers may be abbreviated and/or use abbreviation iff it helps readability
  • prefer using built-in features instead of hand-crafting lambdas
    • examples
      • correct: const x
      • wrong: \_ -> x
  • prefer using short-hand form for lambdas
    • examples
      • correct: (_ + 1)
      • wrong: \x -> x + 1
  • avoid needless layering of lambdas and function calls
    • examples
      • correct: f g
      • wrong: f (\value -> g value)
  • use fully qualified names
    • fully qualified names lower cognitive overhead by making it clear where a symbol comes from
    • fully qualified names lead to much shorter and more manageable lists of imports
    • fully qualified names do not pollute the namespace and prevent name clashes
    • examples
      • import syntax
        • correct: import Foo.Bar as Foo.Bar
        • wrong: import Foo.Bar, because it pollutes the namespace with all symbols exported by Foo.Bar
          • exception: Prelude is implicitly imported, so it is not necessary to qualify its symbols
        • wrong: import Foo.Bar (baz), because it pollutes the namespace with baz, which still may not be universally unique
        • wrong: import Foo.Bar as FB, because it introduces cognitive overhead on the reader
          • exception: Universally well known abbreviations (specifically listed in the coding standard) are acceptable
      • usage syntax
        • correct: Foo.Bar.baz
        • wrong: baz
        • wrong: Bar.baz
        • wrong: FB.baz