Thanks so much for sharing your point of view, despite the reluctance! No need to be apologetic that it’s “more of a feeling”. Feelings are very important indicators of the quality of a design!
I am also reluctant to give my reply, because it might sound like I’m saying “you’re holding it wrong”. In fact my intention is more to present the counterpoint in the hope that we can find a path that provides close to the best of both worlds.
Firstly, I agree with you then when you’re stuck debugging a tricky issue the mental overhead of switching context to add a dependency feels like a lot, not to mention adding {-# LANGUAGE QuasiQuotes #-}
at the top, and whatever other requirements I have forgotten.
I also agree that
"x = " <> show x <> ", smallThing = " <> show smallThing <> ", mediumSizeIdentifier = " <> show mediumSizeIdentifier
is harder to read than
f"x = {x}, smallThing = {smallThing}, mediumSizedIdentifier = {mediumSizedIdentifier}"
but don’t think it’s the length that is significant. It’s not that much longer.
On the other hand, I Kagied for “haskell string interpolation” and the first hit was string-interpolation. Its equivalent is
[i|x = #{x}, smallThing = #{smallThing}, mediumSizedIdentifier = #{mediumSizedIdentifier}|]
and I think it’s hard to say that’s worse than your version. It comes with a few paper-cuts of its own:
- Just like with
OverloadedStrings
, you may have to disambiguate the type with a type signature.
- You have to
{-# LANGUAGE QuasiQuotes #-}
(the Haddock page doesn’t seem to explain this)
- You have to depend upon
string-interpolation
in your cabal file (or equivalent)
- You have to import
Data.String.Interpolate
in every file you want to use it in.
- The quasi-quoter is called
i
so is likely to conflict with variables you want to define yourself!
Suppose someose addressed these problems as follows:
She adds the quasi-quoter under a less common (but still short) name to a custom prelude, and makes sure that QuasiQuotes
is always enabled in her cabal file, before she starts any project.
I think this brings the quasi-quoter option close to par with, say, Python’s. It has a few downsides:
- It’s still a bit longer, in terms of number of characters
- It’s more awkward to type
[i| ... |]
(or whatever) than f"..."
- The error messages are probably worse (but might actually be better)
- It’s non-standard, so you won’t find thousands of Stack Overflow answers and blog posts that describe using it.
On the other hand it has a few upsides:
- It’s not tied to the compiler so can be implemented independently,
- Error messages can be made custom
And the Python version has some downsides:
- There’s only one choice
- It can’t be improved without depending on the language implementation team to accept it and an interpreter author to implement it
It think that before changing the language we have to be really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really sure that there isn’t a library level solution that can be made almost as nice as a language level solution (and nicer in some ways). In this case I don’t think we’ve exhausted the design space of format strings via quasi-quoters.