JordanMartinez / purescript-jordans-reference

Learn PureScript with this "clone and play" repository
https://jordanmartinez.github.io/purescript-jordans-reference-site/
588 stars 73 forks source link

Add Domain Driven Design-related Design Patterns #288

Closed digital-stoic closed 5 years ago

digital-stoic commented 5 years ago
Section:
  Design Pattern

Issue Type:
  Enhancement and/or ToResearch 

Folder/File(s):
  - Design Patterns/ReadMe.md

Body

I think your Application Structure based on DDD Onion Architecture is a very good start, but I would expand the Domain layer.

Scott Wlaschin, a FP expert warns that Functional Design patterns are very different from Object Oriented patterns (the F# examples are easy to translate into PureScript). Among the very rare DDD+FP resources, his slides and book were for me the most illuminating ones.

I think it would be worth to create (sub-)sections about the following patterns:

JordanMartinez commented 5 years ago

So, let me ask these questions first because I haven't read his book (though I have seen his slides):

Composition is everywhere (Composition is fractal + Types can be composed too)

This sounds more like an FP Philosophical Foundation idea. Meaning, I'd rather people were exposed to this as early as possible rather than "hiding" it (i.e. delaying its appearance until much later) until the design patterns folder.

Use static types for Domain modelling and documentation => Would be relevant to have a dedicated section about Domain Driven Design with FP (and summarize the book Domain Modeling Made Functional)

In short, I agree that a summary of domain modeling should be added somewhere in this repo and near the App Structure folder (whether inside of it or as a new folder). I don't think I cover that well enough yet.

My goal for the App Structure folder (or at least its Monad Transformers / Free explanations) is to explain how to separate pure business logic from impure implementations. In that sense, it might need to be renamed to better reflect what it tries to accomplish.

I tried to make the Projects folder to act like examples of the above app structure where I start to delve more into domain modeling using types. The "guess a random number" game seems to accomplish that but not as well as it could. I don't think the ToC program accomplishes that because it's just one large traverse. I initially started off in the domain modeling via types direction but then realized it wasn't needed.

Use Bind to chain tasks and error handlers

I think this is part of my goal for #246. My current Identity/Box-based Monad explanation helps one first get used to the type signature and understand how it works. I don't yet explain how different monads 'compose' different concepts together.

JordanMartinez commented 5 years ago

Related, but this idea should likely also include the undefined trick:

-- taken from recent Slack channel conversation
undefined :: forall a. Warn (Text "This function contains undefined values") => a
undefined = unsafeCoerce unit

-- what I think they were ultimately referring to
todo :: forall a. IsSymbol msg => Warn (Text "TODO: " + msg) => SProxy msg -> a
todo _ = unsafeCoerce unit

As one is figuring out their design, they can write code that will compile to verify that things work correctly. Then, they can swap out the 'todo' pieces with the correct parts:

-- initial design part
f :: forall a b c. a -> b -> c -> a
f a b _ = someFunction a b (todo (SProxy :: SProxy "Define 'c' here"))

-- When compile, it should output as a compiler warning:
-- "TODO: Define 'c' here"

-- once finalized, implement it
f :: forall a b c. a -> b -> c -> a
f a b c = someFunction a b c
digital-stoic commented 5 years ago

So, let me ask these questions first because I haven't read his book (though I have seen his slides):

* What is the app structure folder (or even this repo) lacking that the FDP stuff contains?

* Of that content, when should I summarize/include/expand those ideas here and how? And when should I simply refer to other works for explanations (e.g. external links and whatnot)?

Composition is everywhere (Composition is fractal + Types can be composed too)

This sounds more like an FP Philosophical Foundation idea. Meaning, I'd rather people were exposed to this as early as possible rather than "hiding" it (i.e. delaying its appearance until much later) until the design patterns folder.

Yes agree... what would have its place in the App structure are the slides 26-30 = composition is fractal from low-level to Service to Use Case to Application

Use static types for Domain modelling and documentation => Would be relevant to have a dedicated section about Domain Driven Design with FP (and summarize the book Domain Modeling Made Functional)

In short, I agree that a summary of domain modeling should be added somewhere in this repo and near the App Structure folder (whether inside of it or as a new folder). I don't think I cover that well enough yet.

My goal for the App Structure folder (or at least its Monad Transformers / Free explanations) is to explain how to separate pure business logic from impure implementations. In that sense, it might need to be renamed to better reflect what it tries to accomplish.

OK

I tried to make the Projects folder to act like examples of the above app structure where I start to delve more into domain modeling using types. The "guess a random number" game seems to accomplish that but not as well as it could. I don't think the ToC program accomplishes that because it's just one large traverse. I initially started off in the domain modeling via types direction but then realized it wasn't needed.

I would rather illustrate with a domain full real-life ambiguities. Start a simple model with types assumptions and incomplete biz logic, implement the biz logic, then refactor to reflect new insights about the domain.

Also emphasize that using the Domain (ubiquitous) language is a great start to self-documentation and less friction in the communication with the domain experts. Similarly, document the business workflow by using types signature before writing the domain functions. Leverage the types to prevent impossible business states.

Use Bind to chain tasks and error handlers

I think this is part of my goal for #246. My current Identity/Box-based Monad explanation helps one first get used to the type signature and understand how it works. I don't yet explain how different monads 'compose' different concepts together.

Mmm, for me the "2-track railway" programming analogy (starting from slides 90) was a real eye-opener.

digital-stoic commented 5 years ago

Related, but this idea should likely also include the undefined trick:

-- taken from recent Slack channel conversation
undefined :: forall a. Warn (Text "This function contains undefined values") => a
undefined = unsafeCoerce unit

-- what I think they were ultimately referring to
todo :: forall a. IsSymbol msg => Warn (Text "TODO: " + msg) => SProxy msg -> a
todo _ = unsafeCoerce unit

As one is figuring out their design, they can write code that will compile to verify that things work correctly. Then, they can swap out the 'todo' pieces with the correct parts:

-- initial design part
f :: forall a b c. a -> b -> c -> a
f a b _ = someFunction a b (todo (SProxy :: SProxy "Define 'c' here"))

-- When compile, it should output as a compiler warning:
-- "TODO: Define 'c' here"

-- once finalized, implement it
f :: forall a b c. a -> b -> c -> a
f a b c = someFunction a b c

Yes exactly, it's part of the iterative Domain modelling for me

JordanMartinez commented 5 years ago

Yes agree... what would have its place in the App structure are the slides 26-30 = composition is fractal from low-level to Service to Use Case to Application

Hm... that makes me think of a useful illustration that I could create using Yed. The following description won't make as much sense without a picture to go alongside of it. Rather, it's more of a reminder to myself as to what I'm thinking. The diagram would sequentially expand a program's workflow idea from start to finish at a high level, then break each of those ideas down into smaller ideas, then each of those into smaller ideas, and finally get to the 'impure' things. Arrows would show how composition combines the low-level stuff into a slightly higher-level thing and the higher-level things into the full program.

I would rather illustrate with a domain full real-life ambiguities. Start a simple model with types assumptions and incomplete biz logic, implement the biz logic, then refactor to reflect new insights about the domain.

Also emphasize that using the Domain (ubiquitous) language is a great start to self-documentation and less friction in the communication with the domain experts. Similarly, document the business workflow by using types signature before writing the domain functions. Leverage the types to prevent impossible business states.

That sounds... like something a book would do. Still, I think this would need to go before the mtl/free folder in application structure. Since I don't have a good problem to solve in this way, perhaps I should just use the idea of a card game as that author uses?

At the very least, this is still a piece of the FP puzzle that I'm not as familiar with as I should be. So, it would be a good mental exercise for me to do.

Mmm, for me the "2-track railway" programming analogy (starting from slides 90) was a real eye-opener.

I agree. The visuals are helpful. I also found this migration from an OO pattern to an FP one helpful.

JordanMartinez commented 5 years ago

So, there's a couple of actionable items here:

digital-stoic commented 5 years ago

Yep,

Unfortunately, I'm very short of time these days so I won't be able to contribute soon on these points. That's why my initial pull request (you can delete it) was mostly pointing at the key resources.

JordanMartinez commented 5 years ago

Ok no worries! Thanks for bringing up the issue though. I'll close that PR.

JordanMartinez commented 5 years ago

@matieux I came across another one of Wadler's videos, which pretty much summarizes this entire issue... I wish I would have found this before trying to summarize a lot of what he said in another video when working on the v0.12.0 release: The Power of Composition

digital-stoic commented 5 years ago

Ya I really like his 'railway' analogy and 'layman' approach to describe FP principles

JordanMartinez commented 5 years ago

Closed by #291