The APIs can depend on such types, instead of using String & linked lists for everything that need UTF-8 grapheme clusters & efficient arrays. The fact that String & List currently have a prominent place in the ecosystem is not unseen elsewhere, Erlang used to have the same issue, but they managed to evolve. Now it’s our turn.
My Christmas wishlist:
- Vector readily available
- Text readily available
- A Display typeclass that is for user-facing output
- PartialEq & PartialOrd, superclasses of Eq & Ord.
-
LinkedList
as a type instead of brackets
Bonus: Less arrogance in terms of development experience and more observations of what other languages that are usually disregarded do to improve the baseline levels of programming joy for their users.
I can agree with all of this except for:
What makes these changes so urgent? I don’t understand what the point would be for PartialEq
or PartialOrd
, and I can’t recall seeing anyone else suggest a problem with brackets.
- Vector readily available
- Text readily available
I’m still not sure what “readily available” means.
If cabal and stack by default depended on text
and vector
, and even by default set a custom prelude that exposed Text
and Vector
APIs rather than String
ones wouldn’t that have the same effect?
- A Display typeclass that is for user-facing output
Why does this require changes to base
?
- PartialEq & PartialOrd, superclasses of Eq & Ord.
Yup, this requires changes to base
!
LinkedList
as a type instead of brackets
Do you want type LinkedList = []
, or something more? If more, can it be done in a way that doesn’t horrendously break everything?
I hereby suggest a problem with brackets! They privilege with special syntax something that we shouldn’t particularly be encouraging.
did we forget to mention semigroupoids
[1] in base
? then we can get all the nice “non-empty” invariants out of the box.
Can you explain? I don’t understand what you mean.
Presumably, because that would encourage people to stop making unlawful Show
instances! Also, maybe GHCi etc. could use any new Display
typeclass.
Maybe this is just my relative inexperience showing, but why shouldn’t we be encouraging linked lists? I’m not convinced that Seq
, Array
or Vector
make better tradeoffs in general.
Regarding Partial Ord & Eq: Some things simply cannot have total equality or ordering. For instance Double, Float:
And for a language coming from a culture of mathematical foundations who like correctness, I think it’s a scandal.
and I can’t recall seeing anyone else suggest a problem with brackets.
That’s on me, I used to complain more loudly about that in community spaces
Fundamentally, giving the lion’s share in terms of sequence syntax to a lazy linked list is not good. People use it for everything, encouraged by the fact that base
uses it for everything, and tend to forget about the asymptotic complexity of the structure. It is a structure that often times not what you need, but typing [a]
in a type signature is sooooo convenient.
I don’t mean they should be discouraged, but they shouldn’t be encouraged either. Since they’re so prominent in base they are, currently, actively encouraged.
What we should do instead is, as you hint, encourage people to think about their use case and choose []
, Seq
, Array
, Vector
or Conduit
/Stream
as appropriate. (Seq
is a good default in my opinion.)
Ah, good point. instance Ord Float
is cursed…
And good points also. Though if we’re talking about such radical changes, I’d suggest getting rid of []
in types entirely: just encourage people to choose per-usecase!
Data.Vector & Data.Text in base
. I wouldn’t say in Prelude because of the API clashes.
If cabal and stack by default depended on
text
andvector
, and even by default set a custom prelude that exposedText
andVector
APIs rather thanString
ones wouldn’t that have the same effect?
Uuuuh, as a cabal maintainer I would like to first make sure that you sign a contract with your own blood before implementing such a thing within cabal.
Other languages do it very well without dirty hacks in their package managers, why not us?
Why does this require changes to
base
?
base
ought to promote a non-Show
way of printing a representation of its data structures.
cf: Display in Rust or the difference between the Inspect
and String.Chars
in Elixir, one for pretty-printing data structures and the other to provide the to_string
method.
Do you want
type LinkedList = []
, or something more?
Actually I want type LinkedList = GHC.List.List
, just like bytestring
got the StrictByteString
alias (cf: Strictness and laziness ergonomics · Issue #375 · haskell/bytestring · GitHub)
Though if we’re talking about such radical changes, I’d suggest getting rid of
[]
in types entirely: just encourage people to choose per-usecase!
Yes that’s my point, LinkedList instead of the brackets.
as a cabal maintainer
Two can play at that game! As a CLC member I’d like you to swear on the memory of your entire ancestral tree before asking me to maintain a significantly increased codebase!
What I’m getting at here is an attempt to disentangle the good things we want from the way in which we obtain good things.
Having text
and vector
APIs directly accessible is a good thing. I agree. People seem to be assuming that the only way to make them directly accessible is by putting them in base
. I’m trying to challenge that assumption with thought experiments (not proposals) (such as the cabal idea).
I suggest we discuss what are good things first and then independently discuss how to obtain the good things.
I’m trying to challenge that assumption with thought experiments
Ah sorry, I didn’t take it as such first and that sent me in a rabbit hole of practical implementation details x)
So, my last arguments regarding their inclusion in base are the following:
-
base
ought to be able to use those types for the APIs it exposes -
The complexity of hiding the inclusion of these packages in the package manager is not something I believe we can withstand at this time because it is indeed technically very complex to provide a development experience to users that is not going to be hellish.
That’s no problem, perhaps I shouldn’t have been so concrete. What I’m really saying is “suppose these things weren’t in base
, but there was some other tooling thing that makes life as convenient as if they were”.
Minimalistic alternative: what about creating an official stdlib
package which does nothing but re-export base
, text
, containers
etc., then set the default Cabal project to depend on stdlib
rather than base
? It doesn’t quite solve the API problem, but it does seem like a reasonable way of including the stuff we want to include by default.
Yes, I know about alternative preludes. The differences between this library and other alternate preludes would be:
-
This would be included by default in Cabal projects (in place of the
build-depends: base
which currently exists) -
This would not act as an alternate Prelude per se: the
Prelude
module would be re-exported frombase
without modification -
This would be intentionally minimalistic, acting purely to re-export other libraries (similarly to Arch Linux meta packages)
-
This would be maintained by the CLC, in tandem with the other boot libraries
(Note also this is more in the vein of being a thought experiment than anything final: it just strikes me as a possibility for a neatly minimal approach which nonetheless gives us a lot of what we want.)
I’m not sure I’m comfortable with the thought experiment that restricts its scope to avoid solving the problem of: The APIs of base
use String and lazy linked list not because of proper algorithmic analysis but because Text & Vector were implemented outside of it, and this has to change. What is the thought experiment that will solve this very real problem?