[DRAFT] VERY rough syntax proposal. Suggestions welcome! [DRAFT]
Chunky Imports are designed to reduce verbosity and increase readability of import sections.
To do this, chunky imports extends Haskell 2010 import syntax in two ways:
These are a comma separated list of modules that share a import symbol.
This can reduces the line count and the number of import
words in a document.
Grouping imports into logical groups can make them more coherent and readable.
import Prelude
import System.IO hiding (appendFile)
import List (intercalate, sort)
-- may become
import Prelude, System.IO hiding (appendFile), list(intercalate, sort)
This is an import list whose imports additionally share some prefix module or namespace.
import foo.bar
import foo.bar.baz (qux)
import foo.quux hiding (corge)
--may become
import bar, bar.baz (qux), quux hiding (corge) from bar
import foo
import foo.bar
--is equivalent to
import *, bar from foo
The wildcard will apear in our real world example below.
import Data.Bifunctor
import Data.Char
import Data.Either
import Data.Functor
import Data.List (intercalate, sort)
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Maybe
import Data.String.Interpolate
import Data.Text (Text)
import Data.Versions hiding (str)
import Data.Void
-- becomes
import Bifunctor, Char, Either, Functor, Maybe, Void,
List (intercalate, sort)
List.NonEmpty (NonEmpty ((:|)))
String.Interpolate
Text (Text)
Versions hiding (str)
from Data
Here are two samples inspired by Maerwald et al's awesome ghcup. I leave it to the reader to decide if chunky imports provide an improvement.
import GHCup
import GHCup.Download
import GHCup.Errors
import GHCup.Platform
import GHCup.Requirements
import GHCup.Types
import GHCup.Utils
import GHCup.Utils.File
import GHCup.Utils.Logger
import GHCup.Utils.MegaParsec
import GHCup.Utils.Prelude
import GHCup.Utils.String.QQ
import GHCup.Version
import Control.Exception.Safe
import Control.Monad.Logger
import Control.Monad.Reader
import Control.Monad.Trans.Resource
import Data.Bifunctor
import Data.Char
import Data.Either
import Data.Functor
import Data.List (intercalate, sort)
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Maybe
import Data.String.Interpolate
import Data.Text (Text)
import Data.Versions hiding (str)
import Data.Void
import GHC.IO.Encoding
import Haskus.Utils.Variant.Excepts
import HPath
import HPath.IO
import Language.Haskell.TH
import Options.Applicative hiding (style)
import Options.Applicative.Help.Pretty (text)
import Prelude hiding (appendFile)
import Safe
import System.Console.Pretty
import System.Environment
import System.Exit
import System.IO hiding (appendFile)
import Text.Read hiding (lift)
import URI.ByteString
import *, Download, Errors, Platform, Requirements,
Types, Utils, Version from GHCup
import File, Logger, MegaParsec, Prelude, String.QQ
from GHCup.Utils
import Prelude hiding (appendFile)
import Safe
import Control.Exception.Safe
import Logger, Reader, Trans.Resource from Control.Monad
import Bifunctor, Data, Either, Functor, Maybe, Void,
List (intercalate, sort)
List.NonEmpty (NonEmpty ((:|)))
Text Text)
Versions hiding (str)
String.Interpolate
from Data
import GHC.IO.Encoding
import Haskus.Utils.Variant.Excepts
import Hpath, Hpath.IO
import Language.Haskell.TH
import * hiding (style), Help.Pretty (text)
from Options.Applicative
import URI.ByteString
import Text.Read hiding (lift)
import Console.Pretty, Environment, Exit,
IO hiding (appendFile)
from System
Sample | SLOC | Import symbols | Words | Chars |
---|---|---|---|---|
A | 42 | 42 | 102 | 1088 |
B | 26 | 15 | 86 | 847 |
Delta | -38% | -64% | -15% | -22% |
I have confirmed that the 2010 language standard does not provide compound impdecls. At first glance, no existing extension provides the feature or similar features. Template haskell may allow users to implement the feature for themselves, but I have not reviewed this extension yet.
My current open questions: Does template haskell let us define this facility? Where should I search for discussions of this or similar language features?
Dminuoso suggested that having the "where" at the end of a list of imports is not very readable. This suggests an alternative form:
import Control.Exception.Safe
import GHC.IO.Encoding
import Haskus.Utils.Variant.Excepts
import Hpath, Hpath.IO
import Language.Haskell.TH
import Prelude hiding (appendFile)
import Safe
import Text.Read hiding (lift)
import URI.ByteString
from Ghcup import
*, Download, Errors, Platform, Requirements,
Types, Utils, Version
from GHCup.Utils import
File, Logger, MegaParsec, Prelude, String.QQ
from Control.Monad import
Logger, Reader, Trans.Resource
from Data import
Bifunctor, Data, Either, Functor, Maybe, Void,
List (intercalate, sort)
List.NonEmpty (NonEmpty ((:|)))
Text (Text)
Versions hiding (str)
String.Interpolate
from Options.Applicative import
* hiding (style),
Help.Pretty (text)
from System import
Console.Pretty,
Environment,
Exit,
IO hiding (appendFile)```
+1