# Enforcing the order of declarations

**URL:** <https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172>\
**Category:** Learn\
**Created:** [November 23, 2023, 7:13am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172 "2023-11-23T07:13:57Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/benjamin-thomas/32/2454_2.png) [@benjamin-thomas](https://discourse.haskell.org/u/benjamin-thomas)\
**Post date:** [November 23, 2023, 7:13am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/1 "2023-11-23T07:13:57Z")

</div>

Hello!

I’m looking for a way that could help me enforce a consistent order of declaration in my own code. I’ve happened to develop a strong taste for the style “declare before use”, I guess my brain works like a sinle-pass compiler 🙂

I understand the order of declarations is irrelevant in Haskell due to equational reasoning. But I don’t like to (unecessarily) jump around when reading source code. And overall, I find I make less of a mess when I conform to this kind of constraint.

For reference, this restriction is enforced by the OCaml (and F#) compiler, and can be applied to a TypeScript code base via this [eslint rule](https://eslint.org/docs/latest/rules/no-use-before-define).

So to sum up, to me, this is okay:

```haskell
-- 3
wrapHtml content =
  "<html><body>" <> content <> "</body></html>"

-- 2
myHtml = 
  wrapHtml "Hello, world"

-- 1
main =
  putStrLn myHtml

```

This is okay:

```haskell
-- 1
main =
  putStrLn myHtml

-- 2
myHtml = 
  wrapHtml "Hello, world"

-- 3
wrapHtml content =
  "<html><body>" <> content <> "</body></html>"

```

This is not okay:

```haskell
-- 2
myHtml = 
  wrapHtml "Hello, world"

-- 3
wrapHtml content =
  "<html><body>" <> content <> "</body></html>"

-- 1
main =
  putStrLn myHtml

```

I’d be interested to hear about possible solutions. If that could help, I’m not looking for something 100% strict btw, I’m fine mixing and matching let clauses with where clauses for instance, at the function scope.

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/benjamin-thomas/32/2454_2.png) [@benjamin-thomas](https://discourse.haskell.org/u/benjamin-thomas)\
**Post date:** [November 23, 2023, 12:15pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/3 "2023-11-23T12:15:35Z")

</div>

Yes I understand you don’t think this is a problem. It is indeed a matter of personal preference.

I’ve explored many languages, having that constraint or not, before realizing this is the style that fits my brain better.

I showed a simple example just to illustrate but I do talk in more general terms, i.e. I also want my types to be declared in a predictable fashion., etc.

But an 80/20 solution would be just fine, I just want a bit of consistency.

From my point of view it’s not nightmarish at all, quite the contrary (with proper tooling)

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/benjamin-thomas/32/2454_2.png) [@benjamin-thomas](https://discourse.haskell.org/u/benjamin-thomas)\
**Post date:** [November 23, 2023, 7:28pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/5 "2023-11-23T19:28:12Z")

</div>

> [@maxigit](#):
>
> it is your decision.

Thank you 🙂

> [@maxigit](#):
>
> I also gave you an answer which was to use nested function

I appreciate it but I think you didn’t understand my request, that’s okay.

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [November 23, 2023, 9:56pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/6 "2023-11-23T21:56:41Z")

</div>

I think this could possibly be implemented in hlint or [stan](https://github.com/kowainik/stan), but I don’t know how much work that would be.

---

<div class="post-metadata">

**Author:** ![ocramz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ocramz/32/3713_2.png) [@ocramz](https://discourse.haskell.org/u/ocramz)\
**Post date:** [November 24, 2023, 3:10am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/7 "2023-11-24T03:10:32Z")

</div>

Well, in the specific example you show of HTML generation (using the blaze library perhaps), the generation type is also a monad so within a Html context the order of declarations does indeed matter…

I would have a harder time imagining what declaring types in a certain order (within a single module) would achieve. On a project level the declaration order is induced by the module import graph of course.

---

<div class="post-metadata">

**Author:** ![AntC2](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/antc2/32/1872_2.png) [@AntC2](https://discourse.haskell.org/u/AntC2)\
**Post date:** [November 24, 2023, 3:55am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/8 "2023-11-24T03:55:06Z")

</div>

> [@benjamin-thomas](#):
>
> I’ve happened to develop a strong taste for the style “declare before use”,

Hi benjamin, Haskell is used heavily (AMOT) for writing compilers for recursively-defined languages – that have been the norm since, aww, Algol 1958, and including all modern languages.

‘Recursively-defined’ means that a `block` includes both declarations and expressions; and the expressions might include local declarations (`let` or `where` in Haskell) – which is a `block`; and those local declarations might include expressions; and those expressions might include a `block`; … ad infinitum.

We also get recursive data structures to represent (say) organic chemistry molecules. They’re (recursive structures) everywhere when you start looking for them.

How is your code going to process these structures? Deal with declarations first? but declarations might include expressions? Deal with expressions first? But expressions might include declarations?

So as others have pointed out, you’re making a rod for your own back, which’ll only annoy you with more complex applications.

(Spoken by an ex-`COBOL`/ex-`Fortran` programmer who’d studied just enough `Algol` at college to SCREAM at times `FORWARD PROCEDURE JUSTGOFINDITFORYOURSELF`.)

---

<div class="post-metadata">

**Author:** ![sclv](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sclv/32/71_2.png) [@sclv](https://discourse.haskell.org/u/sclv)\
**Post date:** [November 24, 2023, 6:11am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/9 "2023-11-24T06:11:16Z")

</div>

I would just note that you can enforce ordering with a sequence of `let` clauses as well, should you so desire.

```haskell
let a = ...
in let b = ...
in let c = ...

```

alternately:

```haskell
runIdentity $ do
  let a = ...
  let b = ...
  let c = ...
  return ...

```

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [November 24, 2023, 8:46am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/10 "2023-11-24T08:46:48Z")

</div>

That was my first thought too, but I’m pretty sure OP wants this at the top level.

---

<div class="post-metadata">

**Author:** ![dixonary](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/dixonary/32/1320_2.png) [@dixonary](https://discourse.haskell.org/u/dixonary)\
**Post date:** [November 24, 2023, 12:02pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/11 "2023-11-24T12:02:03Z")

</div>

I understand why you would prefer that approach. The best way to approach this would be via a compiler plugin or, failing that, external tooling.

But I don’t think anyone will have written such a plugin before now, because thinking about programs in a top-to-bottom way is extremely unidiomatic in Haskell (not to mention it forbids certain common kinds of function definitions, such as those with mutual recursion defined at the top level)

* * *

For the sake of satisfying your curiosity, if you really want to enforce some line L such that only things before line L can be used in things after line L and not the other way round, it can be done with some really awful hacks. For example, if using Template Haskell you could add a meaningless splice, which enforces such a line as a side-effect of how it works:

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

This is not recommended for about 50 different reasons.

---

<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:** [November 24, 2023, 7:14pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/12 "2023-11-24T19:14:45Z")

</div>

[Dependency Analysis of Haskell Declarations](https://www.youtube.com/watch?v=jNbb5JVuq-o). Related video about the work GHC performs to allow declarations to appear in any order.

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/benjamin-thomas/32/2454_2.png) [@benjamin-thomas](https://discourse.haskell.org/u/benjamin-thomas)\
**Post date:** [November 24, 2023, 8:48pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/13 "2023-11-24T20:48:41Z")

</div>

> [@AntC2](#):
>
> So as others have pointed out, you’re making a rod for your own back, which’ll only annoy you with more complex applications.

Thanks, I’ll keep that in mind.

> [@tomjaguarpaw](#):
>
> That was my first thought too, but I’m pretty sure OP wants this at the top level.

Indeed 🙂

> [@dixonary](#):
>
> But I don’t think anyone will have written such a plugin before now, because thinking about programs in a top-to-bottom way is extremely unidiomatic in Haskell

Ignoring the special case of mutual recursion do you mean that it is more common to define your functions in “reverse order”? I wouldn’t mind, I just don’t want a mix of both styles, I think it’s messy. If a tool could help me with that I’d use it.

Regarding mutual recursion, if we consider this Haskell code:

```haskell
even :: Int -> Bool
even 0 = True
even n = odd (n - 1)

odd :: Int -> Bool
odd 0 = False
odd n = even (n - 1)

```

OCaml can express the same thing, but forces you to declare both functions as a single unit, with the `and` keyword.

```ocaml
let rec even = function
  | 0 -> true
  | n -> odd (n - 1)
and odd = function
  | 0 -> false
  | n -> even (n - 1)

```

So I just want to note that it is possible to enforce an order of declarations **and** allow expressing mutual recursion.

> [@danidiaz](#):
>
> [Dependency Analysis of Haskell Declarations](https://www.youtube.com/watch?v=jNbb5JVuq-o). Related video about the work GHC performs to allow declarations to appear in any order.

Thanks!

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [November 25, 2023, 10:28am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/15 "2023-11-25T10:28:53Z")

</div>

> [@benjamin-thomas](#):
>
> Ignoring the special case of mutual recursion do you mean that it is more common to define your functions in “reverse order”?

I would say it’s idiomatic to accept that definitions can occur in any order, and I think that’s what @dixonary meant too.

---

<div class="post-metadata">

**Author:** ![silky](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/silky/32/3555_2.png) [@silky](https://discourse.haskell.org/u/silky)\
**Post date:** [November 25, 2023, 12:23pm UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/16 "2023-11-25T12:23:49Z")

</div>

I agree with @jaror; re: hlint; looks like you could start glancing around here - [https://github.com/ndmitchell/hlint/blob/e760b31702a660d6938bddbc573105d42a0280ed/src/GHC/Util.hs#L87](https://github.com/ndmitchell/hlint/blob/e760b31702a660d6938bddbc573105d42a0280ed/src/GHC/Util.hs#L87)

But tracking all the dependencies might get complex; but it could be just a fun exercise in understanding how to hack on hlint anyway.

---

<div class="post-metadata">

**Author:** ![benjamin-thomas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/benjamin-thomas/32/2454_2.png) [@benjamin-thomas](https://discourse.haskell.org/u/benjamin-thomas)\
**Post date:** [November 26, 2023, 7:02am UTC](https://discourse.haskell.org/t/enforcing-the-order-of-declarations/8172/17 "2023-11-26T07:02:47Z")

</div>

> [@silky](#):
>
> I agree with @jaror; re: hlint; looks like you could start glancing around here

Thanks, I take a mental note. I’ll first explore Haskell more fully as-is, maybe I’ll gain new insights as time passes.

Thanks for the template Haskell suggestion @maxigit, I may use this trick here and there to isolate common functions (as a step prior to creating a module)
