# Maintaining haskell programs

**URL:** <https://discourse.haskell.org/t/maintaining-haskell-programs/7166>\
**Category:** Uncategorized\
**Created:** [August 2, 2023, 4:49am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166 "2023-08-02T04:49:13Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![anon58422685](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon58422685](https://discourse.haskell.org/u/anon58422685)\
**Post date:** [August 10, 2023, 9:35pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/85 "2023-08-10T21:35:16Z")

</div>

> [@atravers](#):
>
> …but that _“goto-goto”_ _ ~~bug~~ _ example still beats them all `:-D`

What is the _«goto-goto»_ example? Is this addressed to me?

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [August 10, 2023, 11:50pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/86 "2023-08-10T23:50:45Z")

</div>

> [@anon58422685](#):
>
> With the `where` thing, you had to come up with 2 new names. It creates space for trivial decisions. […]

If people have the time to debate the names of local bindings, they must have run out of bugs to remove from their respective codebase/s - _well done!_

* * *

That _“goto-goto”_ example:

`https://www.imperialviolet.org/2014/02/22/applebug.html`

…which is a poignant example of what happens when syntactic sweetening goes too far - I dare say the majority of us have blundered into this ugly _“idiom”_ enough times to wish _vehemently_ that **it didn’t exist.**

---

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [August 11, 2023, 1:39am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/87 "2023-08-11T01:39:35Z")

</div>

I apologize for offending Kindaro, but I mean this literally: it would be awesome to see how a small production dialect, presumably a team under kindaro’s control, using assiduous block argument abuse, would evolve.

* * *

At this moment, the reason I’m against Lisps are more because I find the parens-infix style, even if you understand how it works, ugly and annoying to read, although I assume with practice you can be accustomed to it. Haskell, on the other hand, with whitespace + infix, can make for extremely readable programs, so any syntactical experimentation, in my view, is welcome.

---

<div class="post-metadata">

**Author:** ![Ambrose](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ambrose/32/5672_2.png) [@Ambrose](https://discourse.haskell.org/u/Ambrose)\
**Post date:** [August 11, 2023, 2:46am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/88 "2023-08-11T02:46:45Z")

</div>

I see Wadler’s Law is popping off in this thread 🤭

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [August 11, 2023, 4:51am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/89 "2023-08-11T04:51:09Z")

</div>

Yes, Wadler’s law:

`http://www.informatik.uni-kiel.de/~curry/listarchive/0017.html`

…and yet people still keep asking for _“niche-syntax”_ extensions!

But this thread is now well and truly off topic: most of the posts from here onwards:

`http://discourse.haskell.org/t/maintaining-haskell-programs/7166/42`

should go into their own thread. Alternately, like another recent thread:

`http://discourse.haskell.org/t/hasura-migrating-to-rust/6620/114`

this one probably should also be locked for the same reasons…

---

<div class="post-metadata">

**Author:** ![Ambrose](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ambrose/32/5672_2.png) [@Ambrose](https://discourse.haskell.org/u/Ambrose)\
**Post date:** [August 11, 2023, 5:10am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/90 "2023-08-11T05:10:44Z")

</div>

I think the various “off topic” tangents [1] in this thread have been the best part. Linear forums such as Discord are an old medium and letting them go off topic (on a leash) is always a fun way to socialize online. Obviously we need rules. But still 🙂

[1] if you can call them that. Discussing BlockArguments and software management and code formatters sure could be argued to be on topic in a thread about Haskell software maintenance

---

<div class="post-metadata">

**Author:** ![vanceism7](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/vanceism7/32/1908_2.png) [@vanceism7](https://discourse.haskell.org/u/vanceism7)\
**Post date:** [August 11, 2023, 5:26am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/91 "2023-08-11T05:26:39Z")

</div>

> [1] if you can call them that. Discussing BlockArguments and software management and code formatters sure could be argued to be on topic in a thread about Haskell software maintenance

I’d say it’s at least loosely related 🤷‍♂️… I’ve learned a lot from following through this thread!

---

<div class="post-metadata">

**Author:** ![anon58422685](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon58422685](https://discourse.haskell.org/u/anon58422685)\
**Post date:** [August 11, 2023, 9:41am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/92 "2023-08-11T09:41:33Z")

</div>

> [@atravers](#):
>
> > [@anon58422685](#):
> >
> > With the `where` thing, you had to come up with 2 new names. It creates space for trivial decisions. […]
> 
> If people have the time to debate the names of local bindings, they must have run out of bugs to remove from their respective codebase/s - _well done!_

Truth be told, projects I work on have known bugs only rarely and briefly. The hard work is adding features. Also, I had one very short argument about names of local bindings in my whole life.

But the issue is not with communication between people so much as it is about having to come up with names. Coming up with names, local or not, is creative work. I want in my life to either do excellent creative work or none at all. `BlockArguments` let me have this because they free me from the mini game of matching parentheses and from some of the work of coming up with names. It is good for me.

I do find that names like `m` and `f` are bad. Cryptic identifiers do confuse me whenever I see them, be it in Haskell or in any other language. There is ambiguity, there is context dependence. For example, `m` can be a monoid, or a monad, or a natural number. The worst offender here is module names. Why do people keep importing stuff qualified as a single letter? This pains me so much.

On the other hand, if you feel the need to document a big definition, splitting it into smaller definitions with the `where` clause, as in your example, is the way to go. You seem to strongly disapprove of the way I like to write stuff… but I think both the `do` and the `where` have their use — the `where` when you want to document, the `do` when you want your sub-expressions to be anonymous. This is the same as with named functions and anonymous functions — both have their use.

* * *

> [@atravers](#):
>
> That _“goto-goto”_ example:
> 
> `https://www.imperialviolet.org/2014/02/22/applebug.html`
> 
> …which is a poignant example of what happens when syntactic sweetening goes too far - I dare say the majority of us have blundered into this ugly _“idiom”_ enough times to wish _vehemently_ that **it didn’t exist.**

To be honest, I cannot empathize because what I see is the use of imperative programming. Using imperative programming to denote pure computations is wrong — of course they will have issues like this. I do not think this example can be extrapolated to Haskell.

* * *

I do not understand the _«sugar»_, _«sweetening»_ line of argument either. Every computational problem can be solved in C, and the solution will be more portable than Haskell. Are all other programming languages a _«sweetening»_ of C then? If so, then what you call _«sugar»_ is a good thing. The task of a language designer is to make the language more commensurate with the human abilities. Overall it seems to me that an attempt at labelling a good thing with a bad word is taking place. _(It is widely known that sugar is harmful.)_

---

<div class="post-metadata">

**Author:** ![anon58422685](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon58422685](https://discourse.haskell.org/u/anon58422685)\
**Post date:** [August 11, 2023, 9:48am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/93 "2023-08-11T09:48:36Z")

</div>

Speaking of Wadler’s law — [I should be delighted to talk about semantics](http://discourse.haskell.org/t/whence-monad-transformers-where-are-distributive-laws/6046/7) instead of the lexical syntax of comments but alas. So, yes.

---

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [August 11, 2023, 3:44pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/97 "2023-08-11T15:44:27Z")

</div>

TBH, with the mainstreaming of ML-style type system languages (Rust), as well as functional programming (Javascript’s functional dialect mainly, Typescript and other languages to a lesser degree, although powerfully typed FP is rare), Haskell’s syntax is a key advantage.

With IO / Monadic code, Haskell is comparable to Python, but in pure code, Haskell beats every language not in its family (Elm / Idris / Purescript) for readable and concise code.

---

<div class="post-metadata">

**Author:** ![brandonchinn178](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/brandonchinn178/32/5103_2.png) [@brandonchinn178](https://discourse.haskell.org/u/brandonchinn178)\
**Post date:** [August 11, 2023, 5:25pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/98 "2023-08-11T17:25:15Z")

</div>

To be fair to @anon58422685, not needing to worry about naming local bindings is one of the things I love about Haskell. Between fmap, function composition, lambda case, etc. I always miss this ability when working in other languages.

But personally, if I do encounter this situation, I usually create local bindings, because if logic is complicated enough to warrant a do block, there’s usually a good name for it. And barring that, I’ve also just used boring parentheses

```haskell
foo
  ( do
      a <- m
      bar a
  )
  $ do
      b <- n
      baz b

```

---

<div class="post-metadata">

**Author:** ![janus](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/janus/32/1060_2.png) [@janus](https://discourse.haskell.org/u/janus)\
**Post date:** [August 11, 2023, 5:47pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/99 "2023-08-11T17:47:30Z")

</div>

> [@Liamzy](#):
>
> it would be awesome to see how a small production dialect, presumably a team under kindaro’s control, using assiduous block argument abuse, would evolve.

[PureScript has BlockArguments](https://github.com/purescript/documentation/blob/master/language/Differences-from-Haskell.md#extensions). So if you took the largest PureScript codebase, would it satisfy your request? Or is there something else in PureScript that means it wouldn’t demonstrate the point the same way?

---

<div class="post-metadata">

**Author:** ![anon58422685](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon58422685](https://discourse.haskell.org/u/anon58422685)\
**Post date:** [August 11, 2023, 6:02pm UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/100 "2023-08-11T18:02:35Z")

</div>

It is not all my ideas. I actually thought they are widely accepted, or at least widely known — except for the one where you write arguments to a function as `do` blocks — this one I have not seen elsewhere.

It could be that Tikhon @Tikhon Jelvis invented the monad list notation back in 2022 — I saw it here: [https://twitter.com/tikhonjelvis/status/1495808960103948291](https://twitter.com/tikhonjelvis/status/1495808960103948291). Beautiful, is it not?

People do something similar with test suites since forever — while `tasty` makes you write a list of checks, other frameworks, in Haskell as well as other languages, ask you to write a giant imperative block like so:

```haskell
it ("does this", check_this);
it (does that", check_that);

```

It is not a far leap to try and build a `tasty` test suite in the same way, as an imperative block — and then why not any other nested list thing!

The idea that identifiers are documentation is seen, for example, here: [https://twitter.com/bitfield/status/980022149099421696](https://twitter.com/bitfield/status/980022149099421696), about 5 years ago.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [August 13, 2023, 3:08am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/102 "2023-08-13T03:08:18Z")

</div>

- 

> [@anon58422685](#):
>
> […] 2 new names […] creates space for trivial decisions. The need to make trivial decisions makes life harder.

- 

> [@brandonchinn178](#):
>
> […] not needing to worry about naming local bindings is one of the things I love about Haskell.

Perhaps you’ll both be happier with using:

- _FP_ :  
[Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs](https://people.eecs.berkeley.edu/~necula/Papers/BackusFunctional.pdf) (starting from section 11 on page 7 of 29);

- …or its successor _FL_ :  
[The FL Project: The Design of a Functional Language](https://theory.stanford.edu/~aiken/publications/trs/FLProject.pdf).

…no local bindings anywhere - enjoy.

---

<div class="post-metadata">

**Author:** ![danidiaz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/danidiaz/32/92_2.png) [@danidiaz](https://discourse.haskell.org/u/danidiaz)\
**Post date:** [August 13, 2023, 9:54am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/103 "2023-08-13T09:54:56Z")

</div>

I shouldn’t have read your comment, now I’m tempted to become a `do` maximalist myself 🤦‍♂️

One tiny benefit of using `do` instead of `$` is that, in HLS, the `do` provides a natural place to show the type of a complex anonymous expression on hover. For example, in this code:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/haskell/original/2X/3/3522bbd3b3bc6d7e7106261de7a4880a6a21cd99.png)

If we hover over the first `do`, we see

 ![image](https://us1.discourse-cdn.com/flex002/uploads/haskell/original/2X/0/0eb5b7c7cc786de3d209bce03aec9f7948d72008.png)

If we had used `(typeRep (Proxy @b))` or `$ typeRep (Proxy @b) $` I’m not sure VSCode would have shown us the type of the `typeRep (Proxy @b)` expression as a whole.

(I might be wrong though… Does HSL have a “show type of selected expression” feature?)

---

<div class="post-metadata">

**Author:** ![hellwolf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hellwolf/32/3020_2.png) [@hellwolf](https://discourse.haskell.org/u/hellwolf)\
**Post date:** [August 13, 2023, 10:07am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/105 "2023-08-13T10:07:02Z")

</div>

It rather reads to me that it is an incidental way of triggering the BlockArguments lexical rules… which is shocking. And not sure it reads well in English if abused…

```haskell
example = fmap
  do \x → x^2 + 1
  do [1, 2, 3]

```

^— Can we squint our eyes and read this in English nicely?

I like BlockArguments for removing brackets, but I didn’t know this one was possible 🙂

Edit:

In fairness, we are just used to read “$” as deliminator, nothing readable about it neither. When I first started Haskell, it was shockingly alien too.

---

<div class="post-metadata">

**Author:** ![danidiaz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/danidiaz/32/92_2.png) [@danidiaz](https://discourse.haskell.org/u/danidiaz)\
**Post date:** [August 13, 2023, 10:10am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/106 "2023-08-13T10:10:11Z")

</div>

You don’t need a `Monad` instance; you can write things like

```haskell
baz :: Int
baz = do 5

```

I guess that if you don’t try to compose or sequence “statements”, the instance is not required at all.

> In fairness, we are just used to read “$” as deliminator, nothing readable about it neither. When I first started Haskell, it was shockingly alien too.

Also, the “true” type of `$` is kind of hairy:

```haskell
($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b

```

Upon reflection, it feels odd to deploy an operator with such a complex type out of mere syntactic convenience.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [August 13, 2023, 10:23am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/108 "2023-08-13T10:23:14Z")

</div>

> [@danidiaz](#):
>
> Also, the “true” type of `$` is kind of hairy:
> 
> ```haskell
> ($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
> 
> ```

**You are not alone:**

- [New type of ($) operator in GHC 8.0 is problematic](https://mail.haskell.org/pipermail/ghc-devs/2016-February/011268.html)

---

<div class="post-metadata">

**Author:** ![hellwolf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hellwolf/32/3020_2.png) [@hellwolf](https://discourse.haskell.org/u/hellwolf)\
**Post date:** [August 13, 2023, 10:25am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/109 "2023-08-13T10:25:22Z")

</div>

> [@danidiaz](#):
>
> Upon reflection, it feels odd to deploy an operator with such a complex type out of mere syntactic convenience.

Adding on to that… linear-base has its own “" and it doen't jive well with base's "”… So I might actually also be using do + BlockAguments then 😕 Only thing bother me is how to read it aloud.

---

<div class="post-metadata">

**Author:** ![hellwolf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hellwolf/32/3020_2.png) [@hellwolf](https://discourse.haskell.org/u/hellwolf)\
**Post date:** [August 13, 2023, 10:28am UTC](https://discourse.haskell.org/t/maintaining-haskell-programs/7166/110 "2023-08-13T10:28:55Z")

</div>

I just tried, no, for obvious reason in hindsight.

So, no blockarguments:

```haskell
example = fmap
    (\x -> x^2 + 1)
    [1, 2, 3]

example' = flip map
    [1,2,3]
    $ \x -> x+1

```

with blockarguments:

```haskell
{-# LANGUAGE BlockArguments #-}

-- GHC says no
-- example = fmap
-- $ \x -> x^2 + 1
-- $ [1, 2, 3]

example' = fmap
    do \x ->
        x^2 + 1
    do [1, 2, 3]

example'' = fmap
    do \x ->
        x^2 + 1
    [1, 2, 3]
-- or other combinations

```

Actually I find `example''` might be quite readoable.

Edit: fixed some compilation failures, and add one more example from maxigit. Make intentional multi-line lambda to highlight the fact that it can do that.

[Previous page](https://discourse.haskell.org/t/maintaining-haskell-programs/7166.md?page=4)

[Next page](https://discourse.haskell.org/t/maintaining-haskell-programs/7166.md?page=6)
