OverloadedStringDefault proposal

I’ve tried it, and it works but it is dangerous, unless there is a way to specify a default per project (instead of per file).
You can specify “OverloadedStrings” per project, but in that case it defaulst to String, which might not be the desired type and so without warning.
An example is for example parsing a csv or some JSon and having some code like

      t <- get "high/low"
      case t of 
         "low" -> Low
         "hight" -> High
         ...

Using String would be inefficient and probably not desired.

OverloadedStrings already works by essentially rewriting every string literal "sometext" into fromString "sometext" so the performance will not be any different from the status quo.

Found that in the OverloadedList doc

… (currently, as a special case, string literals benefit from statically allocated compact representation).

Not sure what that mean in practice.

Yeah that’s right, if you look at the Core representation then you’ll see something like this:

mystring = "sometext"

Gets compiled into:

mystring = fromCString# "sometext"#

That "sometext"# is basically a raw bytestring and fromCString# transforms that into a normal Haskell string. If we add overloadedstrings into the mix you’d get something like:

mystring = Text.pack (fromCString# "sometext"#)

And the text package has this rule:

{-# RULES "TEXT literal" forall a.
    pack (GHC.unpackCString# a) = unpackCStringAscii# a #-}

(And there’s another rule for utf8 literals.)

So it rewrites the primitve that generate strings to a primitive that generate Text directly.

5 Likes

You’re late. There already is a proposal to deal with the problem and it’s been accepted. I was hoping somebody other than me would implement it, but that didn’t happen so I’m looking into it.

Even when omitting all the issues with type inference, OverloadedStrings is a broken extension due to: Surprising behavior of ByteString literals via IsString · Issue #140 · haskell/bytestring · GitHub

If this makes it into a GHCXXXX set, I think that would be proof for me to stay far away from those GHC editions.

1 Like

I don’t think that makes it a broken extension, IsString ByteString is simply impossible to define correctly (but the utility outweighs the potential trouble, so here we are).

I find myself quite confused as to why this seemingly basic feature (embedding literals into code) is impossible to implement. Both compilation-time execution and Template Haskell are deemed bad (someone could fire the missiles), so the answer is just no feature at all. And then the only viable user-side solution is Template Haskell through some random library, just that instead of "foo" you have to type in [ascii|foo|], how droll.

You can’t convert unicode literals. How is that not broken? It silently truncates and leaves you with garbage.

1 Like

The ByteString instance is broken, the IsString class is merely not powerful enough to support all the expected use cases. Perhaps “not mature enough” is a better description.

So you want to include an extension by default that works some of the time? I hope the GHC SC has stricter rules than that.

1 Like

Not enough unfortunately as it is still not implemented :wink:
How would it work with custom Prelude (I mean can a module reexport the default declaration)?

Is the extension which is broken or the IsString class which is not powerfull enough to deal with Bytestring. Also is it a problem in practice ? (It is not because someone use Bystestring that he/she actually requires unorthodox literal string.

Could you provide with an example ?

Well, of course the extension. It’s the extension which decides to use IsString class and it’s the extension that could error out on bytestring literals. But it doesn’t. It doesn’t even warn.

Yes, why do you think people raised the issue I linked? Because it caught them off-guard and was totally unexpected.

There’s plenty of examples in the issue I linked, including runtime crashes when you use decodeUtf8 on a unicode literal.

1 Like

So if tomorrow I write an instance of IsList for something and it crashes, does that mean the OverloadedList extension is broken ?
Maybe people shouldn’t use OverloadedString for bytestring or don’t mix it with unicode …

Ah well, there goes the static typing and “Haskell is about correctness” :grinning_face_with_smiling_eyes:

Let’s just truncate data and throw runtime errors and include that behavior in our default language edition, because it reflects the spirit of Haskell so well.

</sarcasm>

On a more serious note:

The language extension could maybe be fixed, but it would be a backwards incompatible change. This brings us back to the discussion that @Ericson2314 sparked elsewhere: if we stopped thinking about GHCXXXX as a set of extensions, but a first class language edition, we could also drive more radical changes.

1 Like

Does that mean removing all the No... extensions which enable us to go back to 1998 ? I am all for it.
As it stands, there is no real difference between setting language to GHCxxx or setting default extensions in the cabal file. So in a way, what is the fuss …

So in a way, what is the fuss [?]

Yes, exports are a part of the proposal.

1 Like

Yeah, “There is a report” and “GHC ain’t Haskell”.
However, we are 2023 so the report should to Haskell 2010, there is no need for a -XPatternGuard extension, it’s in the report

3.13 Case Expressions

lexp → case exp of { alts }
alts → alt1 ; … ; altn (n ≥ 1)
alt → pat → exp [where decls]
| pat gdpat [where decls]
| (empty alternative)

gdpat → guards → exp [ gdpat ]
guards → | guard1, …, guardn (n ≥ 1)
guard → pat ← infixexp (pattern guard)
| let decls (local declaration)
| infixexp (boolean guard)

There is even less need for -XNoPatternGuard, it’s not in the report (neither is -XHaskell98).
So, indeed I understand that we won’t remove extensions part of GHCxxx, so what the fuss.
And we won’t for Haskellxx either, so again, what the fuss ? Actually there is no real fuss about Haskellxx …

Congratulations, @maxigit! You’ve just volunteered to deal with all the resulting breakage, since that is apparently “no real fuss” for you…