hpack icon indicating copy to clipboard operation
hpack copied to clipboard

Where applicable, use `elif` in Cabal files

Open mpilgrem opened this issue 9 months ago • 5 comments

elif was introduced in cabal-version: 2.2 (released March 2018). For example:

when:
- condition: os(windows)
  then:
    source-dirs: windows
  else:
    when:
    - condition: "os(darwin) || os(linux)"
      then:
        source-dirs: unix-like
      else:
        source-dirs: unsupported-os

becomes:

if os(windows)
  hs-source-dirs:
      windows
elif os(darwin) || os(linux)
  hs-source-dirs:
      unix-like
else
  hs-source-dirs:
      unsupported-os

(In contrast to the current:

if os(windows)
  hs-source-dirs:
      windows
else
  if os(darwin) || os(linux)
    hs-source-dirs:
        unix-like
  else
    hs-source-dirs:
        unsupported-os

)

I have a pull request that implements this:

  • #605

mpilgrem avatar Mar 11 '25 21:03 mpilgrem

@mpilgrem this is a purely cosmetic change, right? Or does this enable any new use cases?

sol avatar Mar 12 '25 00:03 sol

@sol, this does, de facto, only affect the readability of generated Cabal files. However, I think that is not unimportant: an important purpose of Cabal files is to be read by people and not all Hpack users include package.yaml in published packages.

I did not track down much history to the introduction of elif:

  • in a discussion on multiway flags (that went nowhere), somebody observed "We should really add some elif sugar to Cabal 2.0 IMO to avoid those staircase if/else we currently have to endure..."; and
  • elif was added a year later (https://github.com/haskell/cabal/pull/4750)

mpilgrem avatar Mar 12 '25 21:03 mpilgrem

(A related but distinct question is: could the Hpack format itself avoid a 'staircase'? Maybe something like:

case:
- condition: os(windows)
  source-dirs: windows
- condition: os(darwin)
  source-dirs: macos
- condition: os(linux)
  source-dirs: linux
- condition: "os(freebsd) || os(openbsd) || os(netbsd)"
  source-dirs: bsd
- otherwise: # Must be last item in list
    source-dirs: unsupported-os

)

mpilgrem avatar Mar 12 '25 22:03 mpilgrem

Maybe even

when:
  os(windows):
    source-dirs: windows
  os(darwin):
    source-dirs: macos
  os(linux):
    source-dirs: linux
  os(freebsd) || os(openbsd) || os(netbsd):
    source-dirs: bsd
  otherwise:
    source-dirs: unsupported-os

Just floating around ideas.

sol avatar Mar 12 '25 22:03 sol

The use of the conditions directly as YAML keys is interesting, but a YAML dictionary is not ordered - I assume you had in mind a list:

when:
- os(windows):
    source-dirs: windows
- os(darwin):
    source-dirs: macos
- os(linux):
    source-dirs: linux
- os(freebsd) || os(openbsd) || os(netbsd):
    source-dirs: bsd
- otherwise:
    source-dirs: unsupported-os

Would you limit the use of conditions as YAML keys to the if...elif..elif...else pattern? Or would you extend that to the if...if...if...if pattern? (With the presence or absence of a final - otherwise: being the toggle?)

EDIT: One advantage of the existing 'conditions as values' is that YAML syntax highlighting helps out in identfying separately the conditions.

mpilgrem avatar Mar 12 '25 23:03 mpilgrem