
A Sticky String Quandary - hyperpape
http://www.stephendiehl.com/posts/strings.html
======
teh
I read this and I agree with everything that he says - but I also think it
makes Haskell look worse than it is to some passer-by.

My impression is that the Haskell community is very self-critical (which is
great), but someone just peeking in from the outside might think that Haskell
is still in the random hobby project stage, and that it still hasn't figured
out strings.

That's totally not the case though! Strings are solved, just a bit annoying to
use sometimes. We're running Haskell in production and it's amazingly stable
and hard to break.

I wish the community was bigger though, that's why I'm posting this to
encourage everyone to try it.

~~~
StefanKarpinski
Stability seems like an orthogonal issue to the standard string representation
being "quite possibly the least efficient (non-contrived) representation of
text data possible". As a production Haskell user, what do you do when you
have to load a large amount of text data?

~~~
tome
> As a production Haskell user, what do you do when you have to load a large
> amount of text data?

Use Text
[https://hackage.haskell.org/package/text](https://hackage.haskell.org/package/text)

"The Text type represents Unicode character strings, in a time and space-
efficient manner. This package provides text processing capabilities that are
optimized for performance critical use, both in terms of large data quantities
and high speed."

~~~
StefanKarpinski
Isn't "hackage" the not-fully-vetted / unstable namespace of packages? Is it
recommended to use hackage packages in production systems?

~~~
Chris_Newton
In the case of the text package, it’s a well-respected _de facto_ standard
regardless of its official status, and probably as safe a dependency as you’re
ever going to get in practice.

Anecdotally, everything serious I write in Haskell uses Data.Text by default
these days, and just converts to and from other representations like String as
necessary. It’s mildly inconvenient for things like writing Show instances or
integrating with a library that uses a different convention, but still better
in almost any context than using String by default IME.

------
guard-of-terra
Haskell has well known deficiences in its std lib (Prelude).

I would make a conjecture that it's also true for Lisps (quality of std lib is
poor often) and other powerful libraries.

On other hand, languages of simpler kind, like Java or Python, have more
adequate std libs.

It's because, for a really powerful language std lib has to be opinionated.
And people understand that but they can't agree on something. So they live
with whatever common denominator. And lost a lot of traction there.

A counterexample is Clojure where std lib is very nice if heavily skewed
towards FP, reinforcing my point.

~~~
wyager
Complaints about Haskell's prelude usually fall strictly under the definition
of "first-world problems".

"Ugh, this length function isn't parameterized over the integrals?"

Or, alternatively:

"Ugh, this length function is parameterized over the foldables?"

People will never agree what's best, but it doesn't really matter. One nice
thing about Haskell is that all the "default" functions, types, and data
structures are just imported from the Prelude library. You can just import
your own version if you want, and people do that.

~~~
seagreen
I wish this was the case, but it's not. A bad string type and lots of partial
functions are legitimate red flags, not "first world problems".

~~~
wyager
> A bad string type

It's only bad in the sense that it's inefficient. It's preferable to most
other string types in many ways. It's also totally reasonable to have in the
prelude: [] is there, and Char is there, so really all they've done is slapped
the two together. The current situation (importing ByteString or Text for
performance) is pretty good IMO. Haskell doesn't have Map or Set or anything
in the prelude, so I think it's reasonable to leave powerful packed text types
out as well. In fact, I would even support leaving [] out of the prelude and
making the import of Data.List explicit.

> lots of partial functions are legitimate red flags

This is true, but the fact that we're even complaining about this is a first-
world problem. Other languages have partial behavior _built in_ to the
language. Try going to a python or java developer and telling them "array
access should return an optional type instead of throwing an exception on out-
of-bounds". This is totally reasonable to deal with in Haskell, but
inconceivable in other languages.

~~~
seagreen

      The current situation (importing ByteString or Text for
      performance) is pretty good IMO. Haskell doesn't have Map 
      or Set or anything in the prelude, so I think it's 
      reasonable to leave powerful packed text types out as well.
    

Interesting. Maybe all we have is a community problem then? Since `String` is
right there, and `Text` is both an additional dependency and an import away
`String` gets used in situations it shouldn't.

    
    
      Try going to a python or java developer and telling them
      "array access should return an optional type instead of
      throwing an exception on out-of-bounds".
    

Alright, I think we have synthesis. From a Python programmers perspective the
Prelude issues are somewhat trivial. From a Haskell programmers perspective
it's offensive to good engineering. So it depends on your perspective:)

~~~
wyager
Agreed on both points.

It's unfortunate that people use String just because it's there, or Int when
they should use Word (because Word wasn't added to the Prelude until
recently). For example, it's awful that length returns an Int. It should
return a Word or be generic.

Indeed, the Haskell programmer is the one I'd say lives in "the first world".

