Skip to content

Commit e2158a5

Browse files
committed
Fragmented modules
1 parent 0aee861 commit e2158a5

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

documentation/conventions-patterns-anti-patterns.djot

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,9 @@ addition.
376376

377377
Gleam's type system and custom types enable Gleam programmers to precisely
378378
model their domain in their code. Types definitions that sufficiently encode
379-
the rules of the domain can make it impossible to construct invalid data,
380-
removing many types of bugs, and turning the type definitions into
381-
documentation for the business logic.
379+
the business rules can make it impossible to construct invalid data, removing
380+
many types of bugs, and turning the type definitions into documentation for the
381+
business logic.
382382

383383
For example, say we are making a website, and the visitors to that website can
384384
be logged in users, or they can be guests. All logged in users have an email
@@ -398,6 +398,22 @@ let logged_in_user = Visitor(id: Some(123), email: Some("hi@example.com"))
398398
let guest = Visitor(id: None, email: None)
399399
```
400400

401+
However, this data structure can be constructed with just an email, or just an
402+
id, both states being invalid according to our business rules!
403+
404+
```gleam
405+
let invalid = Visitor(id: Some(123), email: None)
406+
```
407+
408+
A better design would ensure that both the id and the email are present at the
409+
same time, making the invalid states impossible.
410+
411+
```gleam
412+
pub type Visitor {
413+
LoggedInUser(id: Int, email: String)
414+
Guest
415+
}
416+
```
401417

402418
Richard Feldman has an excellent talk on this pattern which can be viewed
403419
[on youtube](https://www.youtube.com/watch?v=IcgmSRJHu_8).
@@ -422,7 +438,21 @@ TODO
422438

423439
### Fragmented modules
424440

425-
TODO
441+
Do not prematurely split up modules into multiple smaller modules, and do not
442+
view large modules as a problem. Instead focus on the business domain and
443+
making the best API for the users of the code.
444+
445+
An API that is split over many modules is harder to understand and requires
446+
more boilerplate to use than one well designed module, and it becomes more
447+
challenging to hide internal implementation details when they have to be
448+
exposed for other modules to use.
449+
450+
If you are having trouble with import cycles, or if multiple modules need to be
451+
imported to perform a simple task with your code, then it may be a sign that
452+
you have split up code that should be a single module.
453+
454+
Evan Czaplicki's talk ["The life of a file"](https://www.youtube.com/watch?v=XpDsk374LDE)
455+
has a wealth of information on this topic.
426456

427457
### Panicking in libraries
428458

@@ -458,8 +488,14 @@ TODO
458488

459489
### Category theory naming
460490

491+
TODO
492+
461493
### Grouping by design pattern
462494

495+
TODO
496+
497+
``` =html
498+
<!--
463499
## OTP anti-patterns
464500

465501
### Processes as state
@@ -477,3 +513,5 @@ TODO
477513
### Organising code with processes
478514

479515
TODO
516+
-->
517+
```

0 commit comments

Comments
 (0)