Re: [Haskell-cafe] Batteries included (Was: GHC is a monopoly compiler)

109 views
Skip to first unread message

Olaf Klinke

unread,
Sep 27, 2016, 5:25:52 PM9/27/16
to haskel...@haskell.org
Can someone please define what exactly a "batteries included" standard library is? IMHO that Python-Haskell comparison is unfair. Although both claim to be general-purpose languages, the focus in Haskell certainly has been on language research for most of its life.
I recently hacked together a web client in python, my first project in that language. Documentation is excellent. Yet I am still horrified I had to use a language that provides so few static guarantees to control megawatt machines.

What puts me off Haskell nowadays is the direct result of Haskell's roots in language research: Often when I come across a package that does what I need, it uses the conduit, lens or another idiom, which are like a language in a language to learn. In milder ways Python seems to suffer the same problem. So please, developers: Write more batteries, but make them expose a neat lambda calculus interface if possible that can be combined freely with other batteries.

Regards,
Olaf


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

Michael Sloan

unread,
Sep 27, 2016, 6:25:48 PM9/27/16
to Olaf Klinke, haskell-cafe
Hi Olaf!

I believe I was the one to recently bring up the subject of "batteries
included". I think wikipedia has a good treatment of it -
https://en.wikipedia.org/wiki/Python_(programming_language)#Libraries

> Python has a large standard library, commonly cited as one of Python's greatest strengths,[77] providing tools suited to many tasks. This is deliberate and has been described as a "batteries included"[29] Python philosophy. For Internet-facing applications, many standard formats and protocols (such as MIME and HTTP) are supported. Modules for creating graphical user interfaces, connecting to relational databases, pseudorandom number generators, arithmetic with arbitrary precision decimals,[78] manipulating regular expressions, and doing unit testing are also included.

Happily, there are efforts underway to fix this problem for Haskell.
In particular, I think the team of people working on the new
foundation library has a very good chance on delivering on the promise
of having batteries included for Haskell. I implore the community to
give foundation a try and pitch in to make it happen. Want to make
sure we don't screw up new-base? Help guide foundation's development.
Here is the link:

https://github.com/haskell-foundation/foundation/

Why is the Python <-> Haskell comparison unfair? We need to be
realistic in our self analysis, and comparing to a very successful
language can indicate what we need to do to make Haskell even more
popular.

Fairness does not matter. The world is not fair, it is made up of
people who have a wide range of opinions and attitude. Many in the
community would love to share Haskell with more people. Why? Because
it is such a valuable thing to learn, and one of the best general
purpose programming languages out there.

Why identify Haskell as a research language, when it has so clearly
grown far beyond that vision? Even if it is considered a research
language, isn't it good for your research to reach the widest audience
possible? This means that the fantastic ideas that make up Haskell /
GHC can reach a wider audience. Some members of that audience are
going to be designing future languages. Do we really want these
future language designers to do that without learning Haskell? I
would prefer that they learn it.

I have recently had a discussion, which I find quite disturbing, where
prominent community members are essentially saying that they are
content with (avoiding success (at all costs)), rather than (avoiding
(success at all costs)). Take a look:
https://www.reddit.com/r/haskell/comments/54gm70/haskell_respect_spj/d83otar

Frankly, these statements frighten and confuse me. It seems blatantly
unreasonable to me, to make the statement that we should be apathetic
towards marketing and lowering the barrier to entry for Haskell.

Sincerely,
Michael

Brandon Allbery

unread,
Sep 27, 2016, 6:32:47 PM9/27/16
to Olaf Klinke, haskell-cafe

On Tue, Sep 27, 2016 at 5:25 PM, Olaf Klinke <o...@aatal-apotheke.de> wrote:
Can someone please define what exactly a "batteries included" standard library is? IMHO that Python-Haskell comparison is unfair. Although both claim to be general-purpose languages, the focus in Haskell certainly has been on language research for most of its life.

It means that useful libraries that most projects use come with it: in a Haskell context, that would be things like text, unordered-containers, and split. It's also a bikeshed, though: for example, H-P insisted on adding OpenGL because it was felt to be important to include some kind of GUI, but the Haskell GUI story is so fragmented and messed up that it doesn't seem really worth it --- and OpenGL basically got the nod solely on being readily portable to Linux/Windows/macOS without having to hunt down extra native libraries, not because it was actually being used by itself. This led to endless discussion on the libraries list.

The complications are:

 - libraries change quickly and dependents tend to start requiring the new versions just as quickly, rendering the batteries included obsolete almost immediately;
 - in the opposite direction, some libraries that come with the compiler because it uses them (notably, containers) are effectively frozen because ghc-api or TH or etc. will break.

Additionally, and causing the above complications to often be fatal, ghc's own library story --- specifically cross-module inlining, which is essential for performance --- results in things which would be sensibly hidden internal details and therefore ABI-breakage-safe often leaking out into the .hi file for cross-module inlining, making the internals part of the public ABI. This is really the primary cause of ghc's library nightmares, and why other languages usually don't have these kinds of problems (but older C and C++ code sometimes did, by exposing internals in header file macros, again for speed; original mh (not nmh) and KDE 1/2 (but not 3.x or later) are examples). But you can't really generate code from Haskell with any reasonable performance unless you resort to either cross-module inlining (ghc) or whole-program compilation (jhc). :( Tools like cabal-install and stack have to do all sorts of otherwise "nonsensical extra work" to try to avoid running headlong into this.

--
brandon s allbery kf8nh                               sine nomine associates
allb...@gmail.com                                  ball...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

Joachim Durchholz

unread,
Sep 27, 2016, 7:14:23 PM9/27/16
to haskel...@haskell.org
Am 27.09.2016 um 23:25 schrieb Olaf Klinke:
> Can someone please define what exactly a "batteries included"
> standard library is?

Anything you'll typically need is already available.
For some value of "typically need", so it's slightly squishy - here's a
list of batteries I'd like included:
- Reading/writing files
- Reading over HTTP (reliably - HTTP is surprisingly complex)
- Search&replace in test streams
- Easy-to-use string->string maps
- JSON parsing and printing (bonus points for YAML)
- GUI stuff
- Website stuff
- Sending mails
- Solid ecosystem:
- build system,
- library directory,
- no-brainer automated testing support.
(Complicated testing means more bugs in test code than in
production code - this diverges.)

> IMHO that Python-Haskell comparison is unfair.
> Although both claim to be general-purpose languages, the focus in
> Haskell certainly has been on language research for most of its life.

I do not think that Python actually comes with all batteries included.
And in some areas support is pretty bad.

> I recently hacked together a web client in python, my first project
> in that language. Documentation is excellent. Yet I am still
> horrified I had to use a language that provides so few static
> guarantees to control megawatt machines.

That, and the idea that class and function declarations are executable
statements.
Circular dependencies are "handled" by passing partially-initialized
objects around; the Python interpreter handles this with no problems,
but programmers have fun because nobody assumes incomplete initialization.

I.e. Python's language semantics is broken by design in pretty
fundamental areas.

That said, it's good for banging something together quickly. Been there,
done that, got the t-shirt.
Just don't do anything that you need a team for with it, the lack of
guarantees will really start to hurt.

> What puts me off Haskell nowadays is the direct result of Haskell's
> roots in language research: Often when I come across a package that
> does what I need, it uses the conduit, lens or another idiom, which
> are like a language in a language to learn. In milder ways Python
> seems to suffer the same problem.

I think Python shares that problem with Lisp: it's so easy to add
another meta-idiom that too many people actually do this, and most don't
even think about composability or guarantees.

> So please, developers: Write more
> batteries, but make them expose a neat lambda calculus interface if
> possible that can be combined freely with other batteries.

I sense a conflict of objectives here.
Having many batteries pushes you towards wide APIs.
However, the wider an API, the harder it is to make it combinable. More
surface that must be made to match.

Making an API that's feature-complete *and* narrow is really hard and
takes a huge amount of designer and programmer time, plus the
willingness to lose most of your existing user base for an unproven idea
of improvement. This road is a really hard one, and you need corporate
backing or personal obsession to follow it.

Christopher Allen

unread,
Sep 27, 2016, 7:21:42 PM9/27/16
to Joachim Durchholz, Haskell Cafe
Batteries included is a bad idea when the community is this divided.
Relative no-brainer topics in other communities like how text should
be represented are highly contentious.

I'd sooner see some basic test cases hammered out and integrated into
base before a real attempt at this is launched. Something that would
help the Cabal devs.

--
Chris Allen
Currently working on http://haskellbook.com

John Wiegley

unread,
Sep 27, 2016, 8:16:34 PM9/27/16
to Christopher Allen, Haskell Cafe
>>>>> "CA" == Christopher Allen <c...@bitemyapp.com> writes:

CA> Batteries included is a bad idea when the community is this divided.
CA> Relative no-brainer topics in other communities like how text should be
CA> represented are highly contentious.

Our community is not "divided", it simply has a large number of interests,
meaning there is rarely a single standard library choice that benefits all
groups equally: academic, pedagogic, hobbyist, commercial, etc. And exactly
because we're not divided, we naturally avoid favoring the needs of one group
over another.

--
John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2

MarLinn via Haskell-Cafe

unread,
Sep 28, 2016, 1:48:55 AM9/28/16
to haskel...@haskell.org
On 2016-09-28 00:32, Brandon Allbery wrote:
Can someone please define what exactly a "batteries included" standard library is?

The complications are:

 - libraries change quickly and dependents tend to start requiring the new versions just as quickly, rendering the batteries included obsolete almost immediately;
 - in the opposite direction, some libraries that come with the compiler because it uses them (notably, containers) are effectively frozen because ghc-api or TH or etc. will break.

This makes me think the "batteries included" metaphor is the wrong line of thinking for Haskell. Our environment is more like "direct access to the power lines", thanks to hackage and cabal. The potential downside is that "powerlines at your fingertips" can lead to cases of "plug and fry (your brain)". But then why should the environment be dumbed down to low-voltage batteries when the high-voltage-network is part of what got it to where it is?

MarLinn

Imants Cekusins

unread,
Sep 28, 2016, 2:06:23 AM9/28/16
to haskell Cafe
> why should the environment be dumbed down to low-voltage batteries 

well "Hello world" should be simple also for someone who never heard of Haskell before. So no harm in providing the batteries. Open the box, skip the instruction, turn it on.
On the other hand, it is reasonable to expect to be able to switch between the batteries and the mains. Replace power supply unit, even.

I don't see why all these options should not be available or why they conflict.

Tony Morris

unread,
Sep 28, 2016, 2:29:22 AM9/28/16
to haskel...@haskell.org
There is nothing of merit in Python libraries to be learned. Please
don't ruin Haskell to the point of Python.
signature.asc

Joachim Durchholz

unread,
Sep 28, 2016, 2:32:14 AM9/28/16
to haskel...@haskell.org
Am 28.09.2016 um 07:47 schrieb MarLinn via Haskell-Cafe:
> The potential downside is
> that "powerlines at your fingertips" can lead to cases of "plug and fry
> (your brain)". But then why should the environment be dumbed down to
> low-voltage batteries when the high-voltage-network is part of what got
> it to where it is?

You already said it: Because people will fry their brain.

"Powerlines at your fingertips" doesn't apply to Haskell, that's C++ and
(if you will) C as well.
Haskell is more like household AC: All the power that you need on a
day-to-day basis, but carefully shielded, safeguarded and geared towards
useful work instead of fry-your-brain accidents. You can disable the
safeguards (UnsafeIO) and you better know what you're doing, though it's
still not a case of nasal demons.

Joachim Durchholz

unread,
Sep 28, 2016, 3:07:04 AM9/28/16
to haskel...@haskell.org
Am 28.09.2016 um 08:29 schrieb Tony Morris:
> There is nothing of merit in Python libraries to be learned.

That's almost true, but not 100%.
E.g. does Haskell have doctests? I.e. you can write example code in the
API-level docs, and there is tooling that can extract them, run them,
and report whether the examples still work.

There's also the old motto of "nothing is completely useless, it can
still serve as a bad example".

> Please
> don't ruin Haskell to the point of Python.

The Python stdlib is a collection of things people needed. So if you
want a list of batteries that Haskell might be missing, Python's stdlib
is a good shopping list.
You don't want to copy the library API structure, but that danger is
negligible. Python is even more imperative than C++ or Java, it's
dynamically typed, and with these concept differences, what's a good
library design in Python that leverages all the things that Python is
good at is almost automatically neither desirable nor even possible in
Haskell.

Tony Morris

unread,
Sep 28, 2016, 3:09:27 AM9/28/16
to haskel...@haskell.org


On 28/09/16 17:06, Joachim Durchholz wrote:
> Am 28.09.2016 um 08:29 schrieb Tony Morris:
>> There is nothing of merit in Python libraries to be learned.
>
> That's almost true, but not 100%.
> E.g. does Haskell have doctests? I.e. you can write example code in
> the API-level docs, and there is tooling that can extract them, run
> them, and report whether the examples still work.

I've been doing that for years, with the exception that doing so in
Haskell is far superior than in Python for reasons too long to list.

https://hackage.haskell.org/package/doctest

>
> There's also the old motto of "nothing is completely useless, it can
> still serve as a bad example".
>
> > Please
>> don't ruin Haskell to the point of Python.
>
> The Python stdlib is a collection of things people needed. So if you
> want a list of batteries that Haskell might be missing, Python's
> stdlib is a good shopping list.

Where is the useful bit? I have only heard of it, never actually seen it.
signature.asc

Peter

unread,
Sep 28, 2016, 3:22:50 AM9/28/16
to haskel...@haskell.org
What are the advantages of batteries included?

1) It's easier for newcomers to find the appropriate library for common
tasks.
2) Consistency between different programs, as they will mostly use the same
standard libraries for common tasks.

Do these require the batteries to be installed with the compiler? Do they
require the batteries to be installed as a monolithic unit at all? An
"official" wiki page pointing to the recommended packages for common tasks
would seem to achieve the purpose almost as well, but without the
accompanying problems.

As for sets of specific library versions that are known to work well
together, Stackage has already solved that.

--
View this message in context: http://haskell.1045720.n5.nabble.com/Re-Batteries-included-Was-GHC-is-a-monopoly-compiler-tp5843366p5843416.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Joachim Durchholz

unread,
Sep 28, 2016, 4:13:59 AM9/28/16
to haskel...@haskell.org
Am 28.09.2016 um 09:09 schrieb Tony Morris:
>
>
> On 28/09/16 17:06, Joachim Durchholz wrote:
>> Am 28.09.2016 um 08:29 schrieb Tony Morris:
>>> There is nothing of merit in Python libraries to be learned.
>>
>> That's almost true, but not 100%.
>> E.g. does Haskell have doctests? I.e. you can write example code in
>> the API-level docs, and there is tooling that can extract them, run
>> them, and report whether the examples still work.
>
> I've been doing that for years, with the exception that doing so in
> Haskell is far superior than in Python for reasons too long to list.
>
> https://hackage.haskell.org/package/doctest

Ah, sweet.

> for reasons too long to list.

Can somebody with a similar long-time working experience in Haskell
doctests provide such a list?
It would be helpful in more than one way: It would help advocate
Haskell, and to the kind of audience that is interested in high quality
so it's a double win; and it would help other language communities
improve their doctest ecosystem, and I think that's what most
multi-language people would very much like to happen.

Regards,
Jo

Simon Peyton Jones via Haskell-Cafe

unread,
Sep 28, 2016, 8:19:50 AM9/28/16
to John Wiegley, Haskell Cafe
| Our community is not "divided", it simply has a large number of
| interests, meaning there is rarely a single standard library choice
| that benefits all groups equally: academic, pedagogic, hobbyist,
| commercial, etc. And exactly because we're not divided, we naturally
| avoid favoring the needs of one group over another.

Bravo John! You have re-framed the challenge (for challenge it is) as in a constructive way, one that acknowledges or even celebrates our differences, and encourages us to work together. Thank you.

Simon

| -----Original Message-----
| From: Haskell-Cafe [mailto:haskell-ca...@haskell.org] On Behalf
| Of John Wiegley
| Sent: 28 September 2016 01:16
| To: Christopher Allen <c...@bitemyapp.com>
| Cc: Haskell Cafe <haskel...@haskell.org>
| Subject: Re: [Haskell-cafe] Batteries included
|
| >>>>> "CA" == Christopher Allen <c...@bitemyapp.com> writes:
|
| CA> Batteries included is a bad idea when the community is this
| divided.
| CA> Relative no-brainer topics in other communities like how text
| should
| CA> be represented are highly contentious.
|
| Our community is not "divided", it simply has a large number of
| interests, meaning there is rarely a single standard library choice
| that benefits all groups equally: academic, pedagogic, hobbyist,
| commercial, etc. And exactly because we're not divided, we naturally
| avoid favoring the needs of one group over another.
|
| --
| John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B
| B80F
| https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fnewart
| isans.com&data=01%7C01%7Csimonpj%40microsoft.com%7C9ca50ffb913e4bd8d85
| e08d3e734b644%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=1cmogRP206x
| YBhVlCDmjtd9LWhASaSAVCVkYxEhYAak%3D&reserved=0
| 60E1 46C4 BD1A 7AC1 4BA2
| _______________________________________________
| Haskell-Cafe mailing list
| To (un)subscribe, modify options or view archives go to:
| https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.h
| askell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fhaskell-
| cafe&data=01%7C01%7Csimonpj%40microsoft.com%7C9ca50ffb913e4bd8d85e08d3
| e734b644%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=r9Yrp3gngUbqhn0u
| qgpfNaKEEhFwukLZBIeKcvDPrrc%3D&reserved=0

Alex Belanger

unread,
Sep 28, 2016, 9:53:29 AM9/28/16
to Peter, Haskell Cafe

Just a reminder, I think Haskell (the language) is being conflated by `base` (the library).

`base` has exactly the minimum required for GHC to bootstrap and compile itself.

If you guys are interested in an `other-base`, then do it and list that as a dependency in your cabal file.

You choose your dependencies by relevance, but it doesn't affect what Haskell is or capable of. The whole point of having even `base` be a library (and extensions) is what allow Haskell to be such a good research language.

No need to discuss morals on a non-existant problem. Go ahead and make a different base. Companies do this all the time.

Alex.

Vilem-Benjamin Liepelt

unread,
Sep 28, 2016, 10:16:13 AM9/28/16
to Haskell Cafe
I am new to this mailing list and this was the first conversation I took note of.

I study computer science at university and have become very interested in Haskell privately, devoting a large portion of my free time to it. I dream of finding a job with Haskell for my industry placement next year or at least after I finish university. I also have hopes of some day working in a world where the ideas and knowledge incubated in Haskell break the shackles of current OOrthodoxy.

While I am aware that I haven't contributed anything to the community yet, I still thought it might be helpful if I made you aware that the tone of some parts of this conversation were rather bewildering to me, because to date I have perceived the community around Haskell to be made up of mainly extremely devoted and respectful individuals. I believe many newcomers would feel similar.

The style of this conversation honestly cast a temporary doubt over the noble notions that Haskell has been standing for in my mind, as I came under the impression that this must be the usual tone around here.

I dearly hope that this is not the case. I am somewhat relieved with John Wiegley's and SPJ's words, as well as some other conversations on this mailing list that seem to be rather more respectful.

This may seem like another good reason to “avoid success at all cost” — to keep away trolls from this amazing project; but please don't let bashers endanger Haskell's success. Haskell needs an open-minded and educated community, which I am striving to be part of.

Vilem

Joachim Breitner

unread,
Sep 28, 2016, 10:59:09 AM9/28/16
to haskel...@haskell.org
Hi,

Am Mittwoch, den 28.09.2016, 15:06 +0100 schrieb Vilem-Benjamin
Liepelt:
> The style of this conversation honestly cast a temporary doubt over
> the noble notions that Haskell has been standing for in my mind, as I
> came under the impression that this must be the usual tone around
> here.
>
> I dearly hope that this is not the case.

it is not. We are usually very helpful and friendly people.
Occasionally thread like this pops up, but I guess many start ignoring
it (if only due to the sheer size).

A bit unfortunate that this is your first impression, but I’m confident
that you’ll get better impressions as time passes on.

Greetings and enjoy Haskell,
Joachim

--
Joachim “nomeata” Breitner
  ma...@joachim-breitner.dehttps://www.joachim-breitner.de/
  XMPP: nom...@joachim-breitner.de • OpenPGP-Key: 0xF0FBF51F
  Debian Developer: nom...@debian.org
signature.asc

Vilem-Benjamin Liepelt

unread,
Sep 28, 2016, 11:09:22 AM9/28/16
to Joachim Breitner, Haskell Cafe
That's so great to hear, thanks, Joachim!

Best wishes,

Vilem

> Debian Developer: nom...@debian.org_______________________________________________

Tony Day

unread,
Sep 28, 2016, 5:31:50 PM9/28/16
to Alex Belanger, Peter, Haskell Cafe
I've asked for some summer interns and space to do some haskell dev.  I'll have 4 bright python-trained coders, with maybe one FP subject, and 8 weeks to get something done.  In this context, the powers that be gave me haskell with batteries included.  I can't give them *those* batteries - I don't even know what some of them do.

Olaf Klinke

unread,
Sep 28, 2016, 5:39:37 PM9/28/16
to haskel...@haskell.org
I did not intend to start a Python-bashing thread. Most people on this list will agree on which language is superior.

I did not intend to suggest that Haskell is still mainly a research language, nor that it should remain to be. I'd love to see more problems to be tackled with lenses, FRP or GADTs, just to show that it can be done this way. Maybe one day an idiom will prove superior to its competitors and take its place in whatever is the equivalent of base then. I am happy to have packages coexist that use either of String, Text, ByteString.Lazy or ByteString.Strict.

I am a fan of the Unix philosophy: Do one thing, and do it well. There are modules in base that are very good examples of this: Data.Map provides just one data structure with a very easy interface, no newtypes, no typeclasses. The user needs no knowledge of how it is implemented, but the internals can be exposed if necessary. Control.DeepSeq provides one single typeclass to provide one single functionality.
In Unix the glue between programs are streams of bytes. I feel that the glue between Haskell libraries should be lambda calculus and algebraic datatypes.
So when you write a library that processes HTTP traffic as conduits: Provide a wrapper function whose type does not mention the conduit classes. When you write another efficient text library, provide fromString and toString functions, even if they are inefficient.

As to what kind of batteries should be included:

* I feel that Haskell already has an excellent set of containers for all sorts of tasks.
* It has excellent parsers.
* The web stuff seems less uniform, and my complaints about idioms apply.
* To compete with other recent teaching languages, a really simple GUI library to use within ghci would be fine. (diagrams and GTK?) Quick Basic included "line" and "circle" commands to play with, even though the rest of the language did not prepare me for more advanced languages.
* I know too little about the state of Haskell's number crunching libraries, but it seems that Vector is reasonably efficient nowadays. But what should I use to solve A*x = b? This is a problem so basic that is should be solved by a basic library.

I like Peter's suggestion of an official wiki highlighting the state-of-the-art packages for common tasks.

As to the versioning and backward compatibility issues of a standard library: In my eyes the whole concept of version numbers is broken. Dependencies should be stated in terms of type signatures.

Olaf

Brandon Allbery

unread,
Sep 28, 2016, 5:46:06 PM9/28/16
to Olaf Klinke, haskell-cafe
On Wed, Sep 28, 2016 at 5:39 PM, Olaf Klinke <o...@aatal-apotheke.de> wrote:
* To compete with other recent teaching languages, a really simple GUI library to use within ghci would be fine. (diagrams and GTK?) Quick Basic included "line" and "circle" commands to play with, even though the rest of the language did not prepare me for more advanced languages.

This turns out to be much easier if you assume that Windows and OS X are not worth supporting, or are happy with forcing users on those platforms to jump through annoying hoops (*especially* Windows; there are reasonable ways to get gtk on OS X, even though it doesn't come with the system, but Windows is still the Wild West as far as third party libraries are concerned --- Chocolatey notwithstanding). :/
 
As to the versioning and backward compatibility issues of a standard library: In my eyes the whole concept of version numbers is broken. Dependencies should be stated in terms of type signatures.

And ghc in fact uses hashes generated from this. But this has to include the signatures of internals because they can leak out for inlining --- so you still have more problems than other languages do.

Richard A. O'Keefe

unread,
Sep 28, 2016, 6:14:34 PM9/28/16
to haskel...@haskell.org
m% cabal install doctest
cabal: /usr/bin/ar: permission denied
m% file /usr/bin/ar; ls -l /usr/bin/ar
/usr/bin/ar: Mach-O 64-bit executable x86_64
-rwxr-xr-x 1 root wheel 18160 14 Jan 2016 /usr/bin/ar

What am I doing wrong?

Brandon Allbery

unread,
Sep 28, 2016, 6:20:40 PM9/28/16
to Richard A. O'Keefe, haskell-cafe

On Wed, Sep 28, 2016 at 6:14 PM, Richard A. O'Keefe <o...@cs.otago.ac.nz> wrote:
m% cabal install doctest
cabal: /usr/bin/ar: permission denied

You have a cabal-install built against an older version of the unix package, which was doing an access() call that runs afoul of System Integrity Protection.

Tony Day

unread,
Sep 28, 2016, 6:36:00 PM9/28/16
to Brandon Allbery, Olaf Klinke, haskell-cafe
My solution to the lack of graphics is ipython or a workflow that looks like it - a loop that renders charts, runs code and places results in a markdown file, then rendered in the browser.
That's about as live as you can get mixing Windows and open source.

Theodore Lief Gannon

unread,
Sep 28, 2016, 6:47:29 PM9/28/16
to haskell-cafe
On Wed, Sep 28, 2016 at 2:45 PM, Brandon Allbery <allb...@gmail.com> wrote:
This turns out to be much easier if you assume that Windows and OS X are not worth supporting, or are happy with forcing users on those platforms to jump through annoying hoops (*especially* Windows; there are reasonable ways to get gtk on OS X, even though it doesn't come with the system, but Windows is still the Wild West as far as third party libraries are concerned --- Chocolatey notwithstanding). :/

GTK on Windows is trivial at this point, with stack and LTS 7+. Try it yourself:

stack exec -- pacman -S mingw-w64-x86_64-gtk3
stack install gtk2hs-buildtools
stack install gtk3 --flag gtk3:build-demos
gtk2hs-demo-carsim

(I didn't start 100% clean but I don't *think* there are any other pacman packages required...)

Jerzy Karczmarczuk

unread,
Sep 28, 2016, 7:01:08 PM9/28/16
to haskel...@haskell.org
Le 28/09/2016 à 23:39, Olaf Klinke a écrit :

> I did not intend to start a Python-bashing thread. Most people on this list will agree on which language is superior.

Do you really need to issue religious statements on this forum? Please...
It is as bad, or worse than such claims as "from XXX you cannot learn
anything useful!"
> /.../ it seems that Vector is reasonably efficient nowadays. But what should I use to solve A*x = b? This is a problem so basic that is should be solved by a basic library.
Are you sure? The same "basic" library for a 3*3 equation, and for some
enormous radiosity computation, and for ill-conditioned matrices, and
for equations with constraints, and for Moore-Penrose pseudoinverses,
and ... etc. ? ...

Libraries must, and will evolve and adapt/split, since new algorithms
are constructed every week.
And if you like cute citations, such as "doing one thing well" (of
course, everybody knows the meaning of "well", which is universal and
eternal, no?...), I'll give you my favourite:

"There is one truth, which should be obvious to everybody: - *all* truth
which is obvious to some, is far from being obvious to others".

Jerzy Karczmarczuk

Joachim Durchholz

unread,
Sep 28, 2016, 8:40:49 PM9/28/16
to haskel...@haskell.org
Am 29.09.2016 um 00:35 schrieb Tony Day:
> My solution to the lack of graphics is ipython or a workflow that looks
> like it - a loop that renders charts, runs code and places results in a
> markdown file, then rendered in the browser.
> That's about as live as you can get mixing Windows and open source.

There was a time when this was correct, but it has been gone for almost
a decade now.
Today, you can even choose the abstraction level:
- GTK++ for GUI
- SDL for multimedia
- OpenGL for 3d Graphics

Tony Day

unread,
Sep 28, 2016, 8:47:13 PM9/28/16
to Joachim Durchholz, haskel...@haskell.org
Ok, as live as you can get mixing native Haskell and windows, without the skills to DIY tooling. Are we that far behind?

Joachim Durchholz

unread,
Sep 28, 2016, 9:18:14 PM9/28/16
to haskel...@haskell.org
If there's DIY tooling involved, then yes that is pretty far behind.
I don't think that's necessary; I dimly recall somebody mentioned that
Haskell does have a call interface to C code. The main challenge is to
find ways to "Haskellize" those strictly imperative APIs so they become
useful for the application programmer; I'd categorize that as
"incommensurable" rather than "behind".

Heinrich Apfelmus

unread,
Sep 29, 2016, 10:44:11 AM9/29/16
to haskel...@haskell.org
> Relative no-brainer topics in other communities like how text should
> be represented are highly contentious.

Actually, choosing a good representation for text / strings is not a
no-brainer, and the difficulty can be traced to several features of the
Haskell language that are simply not present in other languages. Some of
these features are:

1) Pattern matching.

We can extract the first character and subsequent characters of a
`String` and distinguish cases while doing so:

isPrefixOf [] _ = True
isPrefixOf (x:xs) [] = False
isPrefixOf (x:xs) (y:ys) = isPrefixOf xs ys

This is not possible in, say, Python.

2) Parametric polymorphism.

The `isPrefixOf` function above is actually polymorphic. It works not
only for `String`, but for any kind of list.

3) Lazy data structures.

We can represent text of *infinite* length!

cycle "Haskell" :: String

And we can use them in a streaming fashion

interact (take 10 . lines) :: IO ()

See also

https://wiki.haskell.org/Simple_Unix_tools

You cannot do this with a standard Python string.


Also, it's not like other languages all agree on their preferred method
of representing strings: NULL-terminated (C) vs "length-byte-first"
(Pascal) comes to mind.


Best regard
Heinrich Apfelmus

--
http://apfelmus.nfshost.com


Christopher Allen wrote:
> Batteries included is a bad idea when the community is this divided.

> Relative no-brainer topics in other communities like how text should

> be represented are highly contentious.
>

> I'd sooner see some basic test cases hammered out and integrated into
> base before a real attempt at this is launched. Something that would
> help the Cabal devs.
>
> On Tue, Sep 27, 2016 at 6:14 PM, Joachim Durchholz <j...@durchholz.org> wrote:


>> Am 27.09.2016 um 23:25 schrieb Olaf Klinke:
>>> Can someone please define what exactly a "batteries included"
>>> standard library is?
>>

>> Anything you'll typically need is already available.
>> For some value of "typically need", so it's slightly squishy - here's a list
>> of batteries I'd like included:
>> - Reading/writing files
>> - Reading over HTTP (reliably - HTTP is surprisingly complex)
>> - Search&replace in test streams
>> - Easy-to-use string->string maps
>> - JSON parsing and printing (bonus points for YAML)
>> - GUI stuff
>> - Website stuff
>> - Sending mails
>> - Solid ecosystem:
>> - build system,
>> - library directory,
>> - no-brainer automated testing support.
>> (Complicated testing means more bugs in test code than in
>> production code - this diverges.)


>>
>>> IMHO that Python-Haskell comparison is unfair.
>>>
>>> Although both claim to be general-purpose languages, the focus in
>>> Haskell certainly has been on language research for most of its life.
>>

>> I do not think that Python actually comes with all batteries included.
>> And in some areas support is pretty bad.


>>
>>> I recently hacked together a web client in python, my first project
>>> in that language. Documentation is excellent. Yet I am still
>>> horrified I had to use a language that provides so few static
>>> guarantees to control megawatt machines.
>>

>> That, and the idea that class and function declarations are executable
>> statements.
>> Circular dependencies are "handled" by passing partially-initialized objects
>> around; the Python interpreter handles this with no problems, but
>> programmers have fun because nobody assumes incomplete initialization.
>>
>> I.e. Python's language semantics is broken by design in pretty fundamental
>> areas.
>>
>> That said, it's good for banging something together quickly. Been there,
>> done that, got the t-shirt.
>> Just don't do anything that you need a team for with it, the lack of
>> guarantees will really start to hurt.


>>
>>> What puts me off Haskell nowadays is the direct result of Haskell's
>>> roots in language research: Often when I come across a package that
>>> does what I need, it uses the conduit, lens or another idiom, which
>>> are like a language in a language to learn. In milder ways Python
>>> seems to suffer the same problem.
>>

>> I think Python shares that problem with Lisp: it's so easy to add another
>> meta-idiom that too many people actually do this, and most don't even think
>> about composability or guarantees.


>>
>>> So please, developers: Write more
>>>
>>> batteries, but make them expose a neat lambda calculus interface if
>>> possible that can be combined freely with other batteries.
>>

>> I sense a conflict of objectives here.
>> Having many batteries pushes you towards wide APIs.
>> However, the wider an API, the harder it is to make it combinable. More
>> surface that must be made to match.
>>
>> Making an API that's feature-complete *and* narrow is really hard and takes
>> a huge amount of designer and programmer time, plus the willingness to lose
>> most of your existing user base for an unproven idea of improvement. This
>> road is a really hard one, and you need corporate backing or personal
>> obsession to follow it.

Christopher Allen

unread,
Sep 29, 2016, 10:52:44 AM9/29/16
to Heinrich Apfelmus, Haskell Cafe
When parametricity isn't an option, utf-8 is taken for granted, the
language is ambiently strict, it's quite a bit more straight-forward
what you want to do, even if the actual implementation is not trivial.

I'm not saying the decision should be trivial for us, I'm saying that
any attempt to unify the disparate things Haskell programmers want is
going to be much harder than it would be with other languages and
ecosystems.

Also, I use this library for my work regularly:

https://github.com/snoyberg/mono-traversable/blob/17eebcfa2e96e923270e1284675456a76e680119/mono-traversable/src/Data/Sequences.hs#L1236-L1237

With Text (Strict | Lazy) and ByteString (Strict | Lazy)

This suits me fine, but I know people for whom mono-traversable is a hard-no.

--
Chris Allen
Currently working on http://haskellbook.com

Joachim Durchholz

unread,
Sep 29, 2016, 11:18:43 AM9/29/16
to haskel...@haskell.org
Am 29.09.2016 um 16:43 schrieb Heinrich Apfelmus:
> Also, it's not like other languages all agree on their preferred method
> of representing strings: NULL-terminated (C) vs "length-byte-first"
> (Pascal) comes to mind.

Each language does define its preferred string representation.

Heinrich Apfelmus

unread,
Sep 29, 2016, 11:33:51 AM9/29/16
to haskel...@haskell.org
> * To compete with other recent teaching languages, a really simple
> GUI library to use within ghci would be fine. (diagrams and GTK?)
> Quick Basic included "line" and "circle" commands to play with, even
> though the rest of the language did not prepare me for more advanced
> languages.

You mean, like this?

http://apfelmus.nfshost.com/temp/hyper-haskell-sneak-peek.png


It's a project that I'm currently working on, called

HyperHaskell
- the strongly hyped Haskell interpreter -

Well, it's supposed to be strongly hyped, but currently, only few people
know about it. Could you give me a hand with, uh, hyping this? I'm not
good at this.


Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com

Richard A. O'Keefe

unread,
Sep 29, 2016, 10:00:54 PM9/29/16
to haskel...@haskell.org

On 30/09/16 3:43 AM, Heinrich Apfelmus wrote:

> Also, it's not like other languages all agree on their preferred method
> of representing strings: NULL-terminated (C) vs "length-byte-first"
> (Pascal) comes to mind.

Just in support of that claim, Java *changed* its implementation
of strings. Originally,
someString.substr(beginIndex, endIndex)
took O(1) time and space whatever the values of
someString, beginIndex, and endIndex.
These days it takes O(endIndex - beginIndex) time and space.

And yes, that DID mean that the performance characteristics of many
Java programs changed without their authors knowing or intending it.

Moritz Angermann

unread,
Sep 29, 2016, 10:04:58 PM9/29/16
to Heinrich Apfelmus, haskel...@haskell.org

> http://apfelmus.nfshost.com/temp/hyper-haskell-sneak-peek.png
>
>
> It's a project that I'm currently working on, called
>
> HyperHaskell
> - the strongly hyped Haskell interpreter -
>
> Well, it's supposed to be strongly hyped, but currently, only few people know about it. Could you give me a hand with, uh, hyping this? I'm not good at this.
>

Nifty!

- How does this compare to jupyter (ipython) with the haskell kernel?
- Is it on GitHub or somewhere?

Cheers,
Moritz

Richard A. O'Keefe

unread,
Sep 29, 2016, 10:16:30 PM9/29/16
to haskel...@haskell.org

On 30/09/16 4:18 AM, Joachim Durchholz wrote:
> Each language does define its preferred string representation.

Java again: it has *two* string representations baked into the
language.

The Smalltalk system I use most has
- read-only strings (preferred)
- unique read-only strings
- mutable strings
- substrings (positionable read-only slices)
- extensible strings
- streams over strings
- lazy concatenations of strings
- read-only byte arrays viewed as strings
- mutable byte arrays viewed as strings

Other Smalltalks typically have four or more concrete kinds
of string plus streams over strings; the substring,
extensible string, and lazy concatenation libraries
I use could be ported to them.

Joachim Durchholz

unread,
Sep 30, 2016, 2:17:47 AM9/30/16
to haskel...@haskell.org
Am 30.09.2016 um 04:16 schrieb Richard A. O'Keefe:
>
> On 30/09/16 4:18 AM, Joachim Durchholz wrote:
>> Each language does define its preferred string representation.
>
> Java again: it has *two* string representations baked into the
> language.

There is a single standard representation.
I'm not even aware of a second one, and I've been programming Java for
quite a while now.

Unless you mean StringBuilder/StringBuffer (that would be three String
types then). However, these classes are by no means "preferred" in
practice: the vast majority of APIs demands and returns String objects.

Even then, Java has its preferred string representation nailed down
pretty strongly: a hidden array of 16-bit Unicode code points,
referenced by a descriptor object (the actual String), immutable.

> The Smalltalk system I use most has
> - read-only strings (preferred)
> - unique read-only strings
> - mutable strings
> - substrings (positionable read-only slices)
> - extensible strings
> - streams over strings
> - lazy concatenations of strings
> - read-only byte arrays viewed as strings
> - mutable byte arrays viewed as strings

Ah, Smalltalk. I haven't looked at that in ages.
I'll give you that these classes all exist, but I am not sure whether a
Smalltalk programmer would consider them all equivalent or not.

Tobias Dammers

unread,
Sep 30, 2016, 2:44:19 AM9/30/16
to Joachim Durchholz, haskell-cafe

FWIW, C++ has:

- char* and const char*, inherited from C
- wchar_t*, const wchar_t*
- the above, but with an explicit length passed along as a separate argument
- std::string
- std::wstring (is that what it's called?)
- various string implementations, provided by platform APIs and frameworks (QString, LPTCHAR, and other nonsense)

And they all suck - most are really just byte arrays, some try to implement Unicode but fall short, and the ones that do it mostly right are specific to a sub-ecosystem. It's a mess.

And do I need to mention PHP? That one doesn't have a useful string type at all, and also lacks the language feature to build it yourself - you're stuck with broken semantics either way, best you can hope for is that they are only mildly broken and you can get away with it.

C, by the way, shares C++'s problem, except that it doesn't even come with a string type that does bounds checking.

And finally: while Haskell makes you choose between "byte array", "string", and "list of code points", this isn't really awfully different from languages like Java or C#, where you make a similar choice (string? StringBuilder? byte[]?), except that the default is saner (for historical reasons). Well, that, and that there are lazy flavors of the packed string amd bytestring types, which has nothing to do with string type choices and everything with defaulting to and leveraging non-strict semantics.

Joachim Durchholz

unread,
Sep 30, 2016, 3:54:51 AM9/30/16
to Haskell Cafe
Am 30.09.2016 um 08:44 schrieb Tobias Dammers:
> FWIW, C++ has:
>
> - char* and const char*, inherited from C
> - wchar_t*, const wchar_t*
> - the above, but with an explicit length passed along as a separate argument
> - std::string
> - std::wstring (is that what it's called?)
> - various string implementations, provided by platform APIs and
> frameworks (QString, LPTCHAR, and other nonsense)
>
> And they all suck - most are really just byte arrays, some try to
> implement Unicode but fall short, and the ones that do it mostly right
> are specific to a sub-ecosystem. It's a mess.

Yep - preferred type was the zero-terminated byte array, and after that
things have diverged.

> And do I need to mention PHP? That one doesn't have a useful string type
> at all,

It's still a string type :-)

> And finally: while Haskell makes you choose between "byte array",
> "string", and "list of code points", this isn't really awfully different
> from languages like Java or C#, where you make a similar choice (string?
> StringBuilder? byte[]?),

At least in Java, you don't really choose, circumstances dictate.

String are immutable. Nice semantics, O(N^2) for N concatenations.
Vast majority of APIs uses this, most strongly preferred.

StringBuilder is mutable.
In practice, people use it as a scratchpad to construct Strings if they
need a loop. Majority of cases is local variables, libraries with the
purpose of constructing a large output string tend to have a
collect-the-output buffer and pass that around internally but don't
expose it to callers (maybe to callbacks, haven't seen that done though).

byte[] for string manipulation is a really itchy hair shirt, you don't
do that unless very strong reasons compel you to.
I am aware of exactly two use cases: Password storage (to be able to
wipe the data ASAP), and converting from and to external byte streams
that carry text.

So it's all straightforward, and String is really the preferred use case.
There's a lot of things that Java doesn't get quite right, but string
handling is not one of these :-)

Heinrich Apfelmus

unread,
Sep 30, 2016, 4:23:32 AM9/30/16
to haskel...@haskell.org
>> HyperHaskell

>
> Nifty!
>
> - How does this compare to jupyter (ipython) with the haskell kernel?

The overall goal is obviously very similar. To me, the main differences are

* HyperHaskell should be easy to install
(e.g. only cabal and a binary download)

* HyperHaskell behaves more like a desktop application, e.g. worksheets
are loaded from and saved to the local file system.

The latter point is actually the main reason why I couldn't get into
Jupyter at all: It insisted that I manage worksheets in some kind of
database in the browser. Ugh! (There may be other front-ends nowadays,
but last I checked, I didn't find anything official or popular, that's
why I decided to write my own thing.)

On the flip side, HyperHaskell is specialized to Haskell -- you can't
use it with other languages.

> - Is it on GitHub or somewhere?

Not yet, it's still in the "hype" phase. ;-) Expect the following location

https://github.com/HeinrichApfelmus/hyper-haskell

to fill with code in a week or two.


Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com

David McBride

unread,
Sep 30, 2016, 4:44:48 AM9/30/16
to Heinrich Apfelmus, Haskell Cafe
Consider me hyped.  I could never get jupyter to work.

Tillmann Rendel

unread,
Sep 30, 2016, 10:36:25 AM9/30/16
to haskel...@haskell.org
Hi,

Theodore Lief Gannon wrote:
> GTK on Windows is trivial at this point, with stack and LTS 7+. Try it
> yourself:
>
> stack exec -- pacman -S mingw-w64-x86_64-gtk3
> stack install gtk2hs-buildtools
> stack install gtk3 --flag gtk3:build-demos
> gtk2hs-demo-carsim
>
> (I didn't start 100% clean but I don't *think* there are any other
> pacman packages required...)

I had to first work around a pacman issue:

stack exec -- pacman -Sy
stack exec -- pacman -S pacman-mirrors

And then I had to install pkg-config:

stack exec -- pacman -S mingw-w64-x86_64-pkg-config

Then the installation commands you provided worked for me.

However, I could not just run gtk2hs-demo-carsim but had to run the
following to expose the GTK DLLs to the executable:

stack exec -- gtk2hs-demo-carsim

Not trivial, but certainly much better than it used to be.

(Still too hard for beginners in some setups. For example, in Tübingen,
we have an introductionary programming lecture with 500 students. We
cannot provide installation support that scales to that number of
students, so our programming environment has to install flawlessly on
stock Windows laptops, preferably without having to use the command line
at all. We want to spend the first lab session programming, not setting up.)

Tillmann

Theodore Lief Gannon

unread,
Sep 30, 2016, 5:23:37 PM9/30/16
to Tillmann Rendel, Haskell Cafe
D'oh, pkg-config of course. And I took an initial 'pacman -Syu' for granted but I suppose that's not documented anywhere specific to Stack... probably worth doing.

Interesting that you had to invoke through stack exec, tho... do you have dynamic linking in your global config? AFAIK static is default on Windows, so the DLLs don't matter after linking.

Tillmann Rendel

unread,
Sep 30, 2016, 6:35:34 PM9/30/16
to Theodore Lief Gannon, Haskell Cafe
Hi,

Theodore Lief Gannon wrote:
> D'oh, pkg-config of course. And I took an initial 'pacman -Syu' for
> granted but I suppose that's not documented anywhere specific to
> Stack... probably worth doing.

So installing gtk is trivial ...

... assuming you know how to operate pacman and setup pkg-config in a
mingw environment? Almost there, almost. ;)

> Interesting that you had to invoke through stack exec, tho... do you
> have dynamic linking in your global config? AFAIK static is default on
> Windows, so the DLLs don't matter after linking.

I didn't change any global config options related to linking.

Note that the issue is with the gtk DLLs, not ghc-produced DLLs. I guess
gtk is always dynamically linked, and you didn't run into this when you
tested because you have GTK installed system-wide, too.

Theodore Lief Gannon

unread,
Sep 30, 2016, 8:08:44 PM9/30/16
to Tillmann Rendel, Haskell Cafe
There's only one top-level installation involved (stack), and no conditional branches on the process, so I'd say it's hit "trivial with step-by-step instructions" at least. I just failed to write them. ;)

I'll have to check whether I have global GTK. I'm 95% sure I don't, but on the other hand it's been a couple of years since my last full reinstall so I could well have just forgotten about it.

Tillmann Rendel

unread,
Sep 30, 2016, 9:05:33 PM9/30/16
to Theodore Lief Gannon, Haskell Cafe
Hi,

Theodore Lief Gannon wrote:
> There's only one top-level installation involved (stack), and no
> conditional branches on the process, so I'd say it's hit "trivial with
> step-by-step instructions" at least. I just failed to write them. ;)

Ok, good point. Hopefully my experiments can lead to a more complete
instruction being put somewhere.

In my experience, many programming beginners on Windows cannot use the
command line at all, so the whole situation of using stack is new to
them. Also, the default support for copy-and-paste for the Windows
command line is so bad that beginners will probably try to follow the
step-by-step instructions by typing out the commands letter by letter.
Therefore, a long list of simple commands but somewhat cryptic commands
is still not really "trivial".

So I think my question is: Could stack be persuaded somehow to make
`stack install gtk3` "just work" by doing all the necessary
incantations? I'm aware why `cabal install gtk3` can neither install
gtk2hs-buildtools nor install the C library, but maybe stack could make
a different tradeoff there.

Theodore Lief Gannon

unread,
Sep 30, 2016, 10:51:49 PM9/30/16
to Haskell Cafe
On Fri, Sep 30, 2016 at 6:05 PM, Tillmann Rendel <ren...@informatik.uni-tuebingen.de> wrote:
So I think my question is: Could stack be persuaded somehow to make `stack install gtk3` "just work" by doing all the necessary incantations? I'm aware why `cabal install gtk3` can neither install gtk2hs-buildtools nor install the C library, but maybe stack could make a different tradeoff there.

I've actually put direct thought into this. I'm partially responsible for the relative ease on Windows now -- previously Stack wasn't setting up the environment correctly for MinGW -- it was providing an MSYS environment instead, which means full POSIX emulation rather than just a mostly-sufficient translation layer. This distinction is also why there are separate 'pkg-config' and 'mingw-w64-x86_64-pkg-config' (and unfortunately you want the latter, here).

I almost added the system update and pkg-config (since .cabal files directly reference it) to the msys installation process in my PR, but I was dissuaded from it by some comments about issues they had trying to do the same with git:

1. it can fail due to network issues, and getting a consistent state with good user feedback out of a return code inside a sub-shell is more work than anyone's wanted to do yet.

2. the fact that msys includes an arbitrary set of packages, and in fact can upgrade itself without stack's permission or even knowledge, is damaging to the intended promise of reproducible builds.

On top of that, this is solely a Windows concern -- stack doesn't have any desire or reason to be a system package manager elsewhere. So I decided the better option is a separate windows-specific tool, which knows how to deal with stack environments (that's in public library code, so yay) and provides a convenience wrapper for pacman which, among other things, attaches the correct big ugly prefix to package names for you.

I got as far as deciding that it would either be named "stacman" or "Jenga" and then put it on the shelf because, with the environment stuff worked out, plain stack is no longer too much of a hassle for me personally. But, I'm certain it's a plausible and not even particularly difficult project.

Heinrich Apfelmus

unread,
Oct 2, 2016, 11:01:14 AM10/2/16
to haskel...@haskell.org
Dear hyped,

I have uploaded the code to

https://github.com/HeinrichApfelmus/hyper-haskell

It's not a release yet, so no one-click installer yet, but it should be
very easy to get it running after cloning the repository (and
downloading the Electron application). Let me know what you think!


Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com

> ------------------------------------------------------------------------

Richard A. O'Keefe

unread,
Oct 2, 2016, 7:20:38 PM10/2/16
to haskel...@haskell.org

On 30/09/16 7:17 PM, Joachim Durchholz wrote:
> There is a single standard representation.

[for strings in Java]


> I'm not even aware of a second one, and I've been programming Java for
> quite a while now

> Unless you mean StringBuilder/StringBuffer (that would be three String
> types then).

StringBuffer is just a synchronized version of StringBuilder.

However, these classes are by no means "preferred" in
> practice: the vast majority of APIs demands and returns String objects.

The Java *compiler* prefers StringBuilder: when you write a string
concatenation expression in Java the compiler creates a StringBuilder
behind the scenes. I'm counting a class as "preferred" if the
compiler *has* to know about it and generates code involving it
without the programmer explicitly mentioning it.

>
> Even then, Java has its preferred string representation nailed down
> pretty strongly: a hidden array of 16-bit Unicode code points,
> referenced by a descriptor object (the actual String), immutable.

As already noted, that representation changed internally.
And that change is actually relevant to this thread.

The representation that _used_ to be used was
(char[] array, offset, length, hash)
Amongst other things, this meant that taking a substring cost
O(1) time and O(1) space, because you just had to allocate and
initialise a new "descriptor object" sharing the underlying
array.

Since Java 1.7 the representation is
(char[] array, hash)
Amongst other things, this means that taking a substring n
characters long now costs O(n) time and O(n) space.

If you are working in a loop like
while (there is more input) {
read a chunk of input
split it into substrings
process some of the substrings
}
the pre-Java-1.7 representation is perfect.
If you *retain* some of the substrings, however, you
retain the whole chunk. That was easy to fix by
doing
retain(new String(someSubstring))
instead of
retain(someSubstring)
but you had to *know* to do it.

(Another solution would be to have a smarter
garbage collector that knew about string sharing and
could compact strings. I wrote such a collector for
XPL many years ago. It's quite easy to do a stop-and-
copy garbage collector that does that. But that's not
the state of the art in Java garbage collection, and
I'm not sure how well string compaction would fit into
a more advanced collector.)

The Java 1.7-and-later representation is *safer*.
Depending on your usage, it may either save a lot of
memory or bloat your memory use.


The point is that there is no one-size-fits-all string
representation; being given only one forces you to either
write your own additional representation(s) or to use a
representation which is not really suited to your
particular purpose.

Joachim Durchholz

unread,
Oct 3, 2016, 2:39:31 AM10/3/16
to haskel...@haskell.org
Am 03.10.2016 um 01:20 schrieb Richard A. O'Keefe:
>
> The Java *compiler* prefers StringBuilder: when you write a string
> concatenation expression in Java the compiler creates a StringBuilder
> behind the scenes. I'm counting a class as "preferred" if the
> compiler *has* to know about it and generates code involving it
> without the programmer explicitly mentioning it.

Then Haskell's preferred representation of additive types would be the
updatable record.
Or machine integers are preferably stored in registers because that's
where every new integer is created, RAM is second class...
I think that's stretching things too far.

There are more indicators against your theory:
1) During the lifetime of a program, the vast majority of textual data
is stored in String objects. StringBuilders are just temporary and are
discarded once the String object is built. (That's quantitative, not
qualitative.)
2) The compiler does NOT have to know. Straight from the Java spec:
> 15.18.1. [...] To increase the performance of repeated string
> concatenation, a Java compiler may use the StringBuffer class or a
> similar technique to reduce the number of intermediate String objects
> that are created by evaluation of an expression.
Moreover, the entire paragraph is a non-authoritative remark.

>> Even then, Java has its preferred string representation nailed down
>> pretty strongly: a hidden array of 16-bit Unicode code points,
>> referenced by a descriptor object (the actual String), immutable.
>
> As already noted, that representation changed internally.

Yes, Java 7 changed that to prevent memory leaks from happening.

> And that change is actually relevant to this thread.

I have been thinking about that argument and do not think it is valid in
a Java context. Java programmers are used to unexpected performance
changes, mostly due to changes in the garbage collector.

It's also just a single function that changed behaviour, and definitely
not the most common one even if it's pretty important.

> The representation that _used_ to be used was
> (char[] array, offset, length, hash)
> Amongst other things,

Not really...

> this meant that taking a substring cost
> O(1) time and O(1) space, because you just had to allocate and
> initialise a new "descriptor object" sharing the underlying
> array.

"You" never had. This all happened behind the scenes, an implementation
detail.

> If you are working in a loop like
> while (there is more input) {
> read a chunk of input
> split it into substrings
> process some of the substrings
> }
> the pre-Java-1.7 representation is perfect.
> If you *retain* some of the substrings, however, you
> retain the whole chunk. That was easy to fix by
> doing
> retain(new String(someSubstring))
> instead of
> retain(someSubstring)
> but you had to *know* to do it.

Okay, now i get the point.
It's a pretty specialized kind of code though. Usually you don't care
much about how much of some input you retain, because more than 50% of
the input strings are retained anyway (if you even do retain strings).

It did have the potential for a memory leak, but now we're getting into
a pretty special corner case here.

Plus it still does not change a bit about that String is the standard
representation in Java, not StringBuffer nor byte[]. The programmer(!)
isn't confused about selecting which one, and that was the point
originally made.

Diving into implementation details just to prove that wrong isn't going
to change that the impression that Java's string representations are
confusing was just the result of first impressions without actual practice.

> (Another solution would be to have a smarter
> garbage collector that knew about string sharing and
> could compact strings. I wrote such a collector for
> XPL many years ago. It's quite easy to do a stop-and-
> copy garbage collector that does that. But that's not
> the state of the art in Java garbage collection,

Agreed.

> and
> I'm not sure how well string compaction would fit into
> a more advanced collector.)

Since Java's standard use case is long-running server programs, most if
not all Java GCs are copying collectors nowadays. So, this would be a
good fit in principle.
It might have unfavorable trade-offs with other use cases though. It's
quite possible that they implemented this, benchmarked it, and found
they couldn't get it up to competitive speed.

> The point is that there is no one-size-fits-all string
> representation; being given only one forces you to either
> write your own additional representation(s) or to use a
> representation which is not really suited to your
> particular purpose.

I haven't read anybody complain about Java's string representation yet.
That does not mean that nobody does (I'm pretty sure that there are
complaints), it just doesn't concern people much in practice. Most Java
programmers don't deal with this, they use a library like JAXML or
Jackson for parsing (XML resp. JSON), get good-enough performance, and
move on.
Some people used to complain that 16-bit characters are a waste of
memory, but even that isn't considered a big problem - essentially, the
alternatives are out of sight and out of mind.
(It would be interesting to see what happened in a language where the
standard string representation is UTF-8. Given that Unicode requires a
minimum of three bytes for a codepoint nowadays, the UTF-16 advantage of
"character count = storage cell count" has vanished anyway.)

Herbert Valerio Riedel

unread,
Oct 3, 2016, 3:45:37 AM10/3/16
to Tillmann Rendel, Haskell Cafe
On 2016-10-01 at 03:05:23 +0200, Tillmann Rendel wrote:

[...]

> I'm aware why `cabal install gtk3` can neither install
> gtk2hs-buildtools nor install the C library

If you're referring to `cabal` not being able to solve for build-tools
and installing them: that's being addressed in 'cabal new-build', right
now latest cabal new-build can already install the well-known
build-tools (alex, happy, etc...).

If you want cabal to install C libraries, you have to package them as
Cabal packages first. I did that e.g. with

http://hackage.haskell.org/package/lzma-clib

for Windows' sake, but it's still an unsatisfying workaround for lack of
a proper system package management for C libraries in Windows. I hope
that something like Chocolatey will become the de-facto standard on
Windows in the foreseeable future.

Joachim Durchholz

unread,
Oct 3, 2016, 4:37:32 AM10/3/16
to haskel...@haskell.org
Am 03.10.2016 um 09:45 schrieb Herbert Valerio Riedel:
> On 2016-10-01 at 03:05:23 +0200, Tillmann Rendel wrote:
>
> [...]
>
> lack of
> a proper system package management for C libraries in Windows. I hope
> that something like Chocolatey will become the de-facto standard on
> Windows in the foreseeable future.

I woudn't hold my breath (yet).
Packaging systems are barely mature enough to offer satisfactory support
simplified use cases like single ABI (Linux package managers) or single
programming language (Cabal, Maven, SBT).
Throwing in mixed-language support can be made to work easily (even
Maven does this, in a half-assed way), but making it work well is still
a "need more experience" topic.

Regards,
Jo

Reply all
Reply to author
Forward
0 new messages