@@ -376,9 +376,9 @@ addition.
376376
377377Gleam's type system and custom types enable Gleam programmers to precisely
378378model 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
383383For example, say we are making a website, and the visitors to that website can
384384be 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"))
398398let 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
402418Richard 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
477513### Organising code with processes
478514
479515TODO
516+ -->
517+ ```
0 commit comments