7 ineffective coding habits many f# programmers don't have
TRANSCRIPT
![Page 1: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/1.jpg)
7 ineffectivecodinghabitsMANYF#programmersDON’Thave
![Page 2: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/2.jpg)
BuildStuff ‘14
![Page 3: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/3.jpg)
![Page 4: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/4.jpg)
habitˈhabɪt/
A settled or regular tendency or practice, especially one that is hard to give up.
![Page 5: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/5.jpg)
“I’m not a great programmer; I’m just a good programmer
with great habits.”
- Kent Beck
![Page 6: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/6.jpg)
Noisy CodeVisual DishonestyLego NamingUnderabstractionUnencapsulated StateGetters and SettersUncohesive Tests
![Page 7: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/7.jpg)
@theburningmonk
does the language I use make a difference?
![Page 8: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/8.jpg)
“Programming languages have a devious influence: they shape our thinking
habits.”
- Edsger W. Dijkstra
![Page 9: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/9.jpg)
Noisy Code
![Page 10: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/10.jpg)
@theburningmonk
![Page 11: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/11.jpg)
![Page 12: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/12.jpg)
@theburningmonk
![Page 13: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/13.jpg)
@theburningmonk
every LOC is a cost
![Page 14: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/14.jpg)
@theburningmonk
more code
more chance for bugs
![Page 15: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/15.jpg)
@theburningmonk
more code
more engineers
![Page 16: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/16.jpg)
@theburningmonk
![Page 17: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/17.jpg)
@theburningmonk
You should do whatever possible to increase the productivity of individual programmers in terms of the expressive power of the code they write. Less code to do the same thing (and possibly better). Less programmers to hire. Less organizational communication costs.
![Page 18: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/18.jpg)
@theburningmonk
You should do whatever possible to increase the productivity of individual programmers in terms of the expressive power of the code they write. Less code to do the same thing (and possibly better). Less programmers to hire. Less organizational communication costs.
![Page 19: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/19.jpg)
does the language I use make a difference?
![Page 20: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/20.jpg)
@theburningmonk
![Page 28: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/28.jpg)
@theburningmonk
Recap
![Page 29: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/29.jpg)
@theburningmonk
no { }no nulls
fewer syntactic noise
![Page 30: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/30.jpg)
@theburningmonk
fewer code
fewer noise
![Page 31: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/31.jpg)
@theburningmonk
fewer noise
higher SNR
![Page 32: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/32.jpg)
@theburningmonk
fewer code
more productivity
![Page 33: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/33.jpg)
- Dan North
“Lead time to someone saying thank you is the only reputation
metric that matters.”
![Page 34: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/34.jpg)
Visual Dishonesty
![Page 35: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/35.jpg)
“…a clean design is one that supports visual thinking so
people can meet their informational needs with a
minimum of conscious effort.”
- Daniel Higginbotham (www.visualmess.com)
![Page 36: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/36.jpg)
@theburningmonk
public void MyCleverMethod( int firstArg, string secondArg)
signifies hierarchy
![Page 37: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/37.jpg)
“You convey information by the way you arrange a design’s elements in relation to each other. This information is understood
immediately, if not consciously, by the people viewing your designs.”
- Daniel Higginbotham (www.visualmess.com)
![Page 38: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/38.jpg)
“This is great if the visual relationships are obvious and accurate, but if they’re not, your audience is going to get confused.
They’ll have to examine your work carefully, going back and forth between the different
parts to make sure they understand.”
- Daniel Higginbotham (www.visualmess.com)
![Page 39: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/39.jpg)
@theburningmonk
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!
Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.
The stable marriage problem is commonly stated as:Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).From the problem description, we can see that we need:* a module for man* a module for woman* a module for orchestrating the experimentIn terms of interaction between the different modules, I imagined something along the lines of…
how we read ENGLISH
see also http://bit.ly/1KN8cd0
![Page 40: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/40.jpg)
@theburningmonk
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!
Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.
The stable marriage problem is commonly stated as:Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).From the problem description, we can see that we need:* a module for man* a module for woman* a module for orchestrating the experimentIn terms of interaction between the different modules, I imagined something along the lines of…
2. top-to-bottom1.left-to-right
how we read ENGLISH
see also http://bit.ly/1KN8cd0
![Page 41: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/41.jpg)
@theburningmonk
how we read CODE
public void DoSomething(int x, int y){ Foo(y, Bar(x, Zoo(Monkey())));}
see also http://bit.ly/1KN8cd0
![Page 42: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/42.jpg)
@theburningmonk
how we read CODE
public void DoSomething(int x, int y){ Foo(y, Bar(x, Zoo(Monkey())));}
2. bottom-to-top
1.right-to-left
see also http://bit.ly/1KN8cd0
![Page 43: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/43.jpg)
@theburningmonk
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage problem using a message passing approach. Naturally, I wanted to answer that question with Erlang!
Let’s first dissect the problem and decide what processes we need and how they need to interact with one another.
The stable marriage problem is commonly stated as:Given n men and n women, where each person has ranked all members of the opposite sex with a unique number between 1 and n in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable”. (It is assumed that the participants are binary gendered and that marriages are not same-sex).From the problem description, we can see that we need:* a module for man* a module for woman* a module for orchestrating the experimentIn terms of interaction between the different modules, I imagined something along the lines of…
2. top-to-bottom
1.left-to-right
how we read ENGLISH
public void DoSomething(int x, int y){ Foo(y, Bar(x, Zoo(Monkey())));}
2. top-to-bottom
1.right-to-left
how we read CODE
see also http://bit.ly/1KN8cd0
![Page 45: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/45.jpg)
@theburningmonk
how we read CODE
let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
see also http://bit.ly/1KN8cd0
![Page 46: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/46.jpg)
@theburningmonk
how we read CODE
let drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)
2. top-to-bottom1.left-to-right
see also http://bit.ly/1KN8cd0
![Page 47: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/47.jpg)
@theburningmonk
{}
![Page 48: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/48.jpg)
@theburningmonk
public ResultType MyCleverMethod( int firstArg, string secondArg, string thirdArg) { var localVar = AnotherCleverMethod(firstArg, secondArg); if (localVar.IsSomething( thirdArg, MY_CONSTANT)) { DoSomething(localVar); } return localVar.GetSomething();}
![Page 49: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/49.jpg)
@theburningmonk
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXX XXX XXXXXXXX XXXXXX XXXXXXXXX XXXXXX XXXXXXXX XXX XXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXX XXXXXXXXX XX XXXXXXXX XXXXXXXXXXX XXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXX XXXXXX XXXXXXXX XXXXXXXXXXXX
![Page 50: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/50.jpg)
@theburningmonk
public ResultType MyCleverMethod( int firstArg, string secondArg, string thirdArg) { var localVar = AnotherCleverMethod(firstArg, secondArg); if (localVar.IsSomething( thirdArg, MY_CONSTANT)) { DoSomething(localVar); } return localVar.GetSomething();}
![Page 51: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/51.jpg)
“This is great if the visual relationships are obvious and accurate, but if they’re not, your audience is going to get confused.
They’ll have to examine your work carefully, going back and forth between the different
parts to make sure they understand.”
![Page 52: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/52.jpg)
@theburningmonk
public ResultType MyCleverMethod( int firstArg, string secondArg, string thirdArg) { var localVar = AnotherCleverMethod(firstArg, secondArg); if (localVar.IsSomething( thirdArg, MY_CONSTANT)) { DoSomething(localVar); } return localVar.GetSomething();}
![Page 53: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/53.jpg)
@theburningmonk
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXX XXX XXXXXXXX XXXXXX XXXXXXXXX XXXXXX XXXXXXXX
XXX XXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXX XXXXXXXXX XX XXXXXXXX XXXXXXXXXXX XXXXXXXX XXXXXXXXXX
XXXXXXXXXXX XXXXXXXX XXXXXX XXXXXXXX XXXXXXXXXXXX
![Page 54: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/54.jpg)
- Douglas Crockford
“It turns out that style matters in programming for
the same reason that it matters in writing.
It makes for better reading.”
![Page 55: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/55.jpg)
@theburningmonk
two competing rules for structuring code in C-style languages
![Page 56: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/56.jpg)
@theburningmonk
Compiler
{ }
Human
{ } + whitespace
![Page 57: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/57.jpg)
@theburningmonk
what if…?
![Page 58: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/58.jpg)
@theburningmonk
Compiler
whitespace
Human
whitespace
![Page 59: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/59.jpg)
@theburningmonk
xxx {}
xxx {}
no braces no
problem
![Page 60: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/60.jpg)
@theburningmonk
There should be one - and preferably only one - obvious way to do it.
- the Zen of Python
![Page 61: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/61.jpg)
@theburningmonk
let myCleverFunction x y z = let localVar = anotherCleverFunction x y
if localVar.IsSomething(z, MY_CONSTANT) then doSomething localVar localVar.GetSomething()
![Page 62: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/62.jpg)
@theburningmonk
XXX XXXXXXXXXXXXXXXX X X X XXX XXXXXXXX XXXXXXXXXXXXXXXXXXXX X X
XX XXXXXXXX XXXXXXXXXXX X XXXXXXXXXX XXXX XXXXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXXX
![Page 63: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/63.jpg)
@theburningmonk
You should do whatever possible to increase the productivity of individual programmers in terms of the expressive power of the code they write. Less code to do the same thing (and possibly better). Less programmers to hire. Less organizational communication costs.
![Page 64: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/64.jpg)
@theburningmonk
Recap
![Page 65: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/65.jpg)
@theburningmonk
|>
![Page 66: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/66.jpg)
@theburningmonk
one way to describe hierarchy
![Page 67: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/67.jpg)
Lego Naming
![Page 68: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/68.jpg)
@theburningmonk
naming is HARD
![Page 69: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/69.jpg)
- Phil Karlton
“There are only two hard things in Computer Science: cache
invalidation and naming things.”
![Page 70: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/70.jpg)
- Mike Mahemoff
“Names are the one and only tool you have to explain what a variable does in every place it
appears, without having to scatter comments everywhere.”
![Page 71: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/71.jpg)
@theburningmonk
Lego NamingGluing common words together in an
attempt to create meaning.
![Page 72: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/72.jpg)
@theburningmonk
Strategy
Process
Create
Add
Controller
Factory
Proxy
ObjectException
Enable
Do
Disable
Service
RemoveCheck
GetSet
Update
Validate
![Page 74: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/74.jpg)
@theburningmonk
this is not naming
![Page 75: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/75.jpg)
@theburningmonk
this is not namingthis is labelling
![Page 76: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/76.jpg)
@theburningmonk
![Page 77: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/77.jpg)
@theburningmonk
![Page 78: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/78.jpg)
![Page 79: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/79.jpg)
@theburningmonk
naming is HARD
![Page 80: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/80.jpg)
@theburningmonk
anonymous functionsaka lambdas
![Page 81: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/81.jpg)
@theburningmonk
fewer things to name
![Page 82: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/82.jpg)
@theburningmonk
words |> Array.map (fun x -> x.Count) |> Array.reduce (+)
![Page 83: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/83.jpg)
@theburningmonk
smaller scopeshorter names
![Page 84: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/84.jpg)
@theburningmonk
![Page 85: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/85.jpg)
@theburningmonk
http://bit.ly/1ZpAByu
When x, y, and z are great variable names
![Page 86: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/86.jpg)
@theburningmonk
"The length of a name should be related to the length of the scope. You can use very short variable names for tiny scopes, but for big
scopes you should use longer names.
Variable names like i and j are just fine if their scope is five lines long."
- Robert C. Martin
![Page 87: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/87.jpg)
@theburningmonk
object expressions
![Page 88: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/88.jpg)
@theburningmonk
enterpriseCrew.OrderBy( (fun c -> c.Current), { new IComparer<Occupation> with
member this.Compare(x, y) = x.Position.CompareTo(y.Position) })
![Page 89: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/89.jpg)
@theburningmonk
enterpriseCrew.OrderBy( (fun c -> c.Current), { new IComparer<Occupation> with
member this.Compare(x, y) = x.Position.CompareTo(y.Position) })
![Page 90: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/90.jpg)
@theburningmonk
fewer things to name
![Page 91: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/91.jpg)
@theburningmonk
tuples + pattern matching
![Page 92: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/92.jpg)
@theburningmonk
tuples + pattern matching
fewer abstractions
![Page 93: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/93.jpg)
@theburningmonk
tuples + pattern matching
fewer abstractions
fewer things to name
![Page 94: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/94.jpg)
@theburningmonk
words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
![Page 95: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/95.jpg)
@theburningmonk
words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
![Page 96: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/96.jpg)
@theburningmonk
words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
![Page 97: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/97.jpg)
@theburningmonk
words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
![Page 98: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/98.jpg)
@theburningmonk
Lego Naming can also be the symptom of a failure to
identify the right level of abstractions.
![Page 99: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/99.jpg)
@theburningmonk
the RIGHT level of abstraction might be smaller than “object”
![Page 100: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/100.jpg)
@theburningmonk
public interface ConditionChecker{ bool CheckCondition();}
![Page 101: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/101.jpg)
@theburningmonk
public interface Condition{ bool IsTrue();}
![Page 102: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/102.jpg)
@theburningmonk
![Page 103: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/103.jpg)
@theburningmonk
type Condition = unit -> bool
![Page 105: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/105.jpg)
@theburningmonk
ClassNotFoundException IllegalArgumentException IndexOutOfBoundsException NoSuchMethodException UnsupportedOperationException
![Page 106: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/106.jpg)
@theburningmonk
ClassNotFound IllegalArgument IndexOutOfBounds NoSuchMethod UnsupportedOperation
![Page 107: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/107.jpg)
@theburningmonk
ArithmeticException ArrayStoreException ClassCastException InstantiationException NullPointerException SecurityException
![Page 108: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/108.jpg)
@theburningmonk
IntegerDivisionByZero IllegalArrayElementType CastToNonSubclass ClassCannotBeInstantiated NullDereferenced SecurityViolation
![Page 109: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/109.jpg)
@theburningmonk
lightweight exception syntax
![Page 110: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/110.jpg)
@theburningmonk
open System open System.IO
exception InsufficientBytes
![Page 111: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/111.jpg)
@theburningmonk
open System open System.IO
exception InsufficientBytes
what could this type represent?
![Page 112: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/112.jpg)
@theburningmonk
Recap
![Page 113: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/113.jpg)
@theburningmonk
F# < > silver bullet
![Page 114: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/114.jpg)
@theburningmonk
anonymous functions
fewer things to name
![Page 115: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/115.jpg)
@theburningmonk
short names
![Page 116: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/116.jpg)
@theburningmonk
tuple + pattern matching
fewer things to name
![Page 117: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/117.jpg)
@theburningmonk
no abstraction is too small
![Page 118: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/118.jpg)
@theburningmonk
lightweight exception syntax
![Page 119: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/119.jpg)
Underabstraction
![Page 120: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/120.jpg)
@theburningmonk
![Page 121: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/121.jpg)
@theburningmonk
public Result DoSomething( int a, string b, string c, string d, DateTime e, DateTime f, string g, MyEnum h)
![Page 122: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/122.jpg)
“If you have a procedure with ten parameters, you probably missed some.”
- Alan Perlis
![Page 124: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/124.jpg)
@theburningmonk
lightweight syntax for types and hierarchies
![Page 125: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/125.jpg)
@theburningmonk
record
![Page 126: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/126.jpg)
@theburningmonk
type Employee = { FirstName : string Surname : string Salary : int<Pound> }
![Page 127: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/127.jpg)
@theburningmonk
type Employee = { FirstName : string Surname : string Salary : int<Pound> } immutable by default
![Page 128: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/128.jpg)
@theburningmonk
let promote emp raise = { emp with Salary <- emp.Salary + raise }
![Page 129: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/129.jpg)
@theburningmonk
mutable state complects
value and time
![Page 130: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/130.jpg)
@theburningmonk
type Employee = { FirstName : string Surname : string Salary : int<Pound> } unit-of-measure
![Page 131: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/131.jpg)
@theburningmonk
[<Measure>]type Pound
e.g. 42<Pound> 153<Pound>
![Page 132: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/132.jpg)
10<Meter> / 2<Second> = 5<Meter/Second>10<Meter> * 2<Second> = 20<Meter Second> 10<Meter> + 10<Meter> = 20<Meter>10<Meter> * 10 = 100<Meter>10<Meter> * 10<Meter> = 100<Meter2>10<Meter> + 2<Second> // error10<Meter> + 2 // error
![Page 133: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/133.jpg)
10<Meter> / 2<Second> = 5<Meter/Second>10<Meter> * 2<Second> = 20<Meter Second> 10<Meter> + 10<Meter> = 20<Meter>10<Meter> * 10 = 100<Meter>10<Meter> * 10<Meter> = 100<Meter2>10<Meter> + 2<Second> // error10<Meter> + 2 // error
![Page 134: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/134.jpg)
@theburningmonk
discriminated unions
![Page 135: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/135.jpg)
@theburningmonk
type PaymentMethod = | Cash | Cheque of ChequeNumber | Card of CardType * CardNumber
![Page 136: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/136.jpg)
Unencapsulated State
![Page 137: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/137.jpg)
@theburningmonk
![Page 138: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/138.jpg)
@theburningmonk
public class RecentlyUsedList { private List<string> items = new List<string>(); public List<string> Items { get { return items; } }
… }
![Page 139: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/139.jpg)
@theburningmonk
immutability
![Page 140: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/140.jpg)
@theburningmonk
type RecentlyUsedList (?items) = let items = defaultArg items [ ]
member this.Items = Array.ofList items
member this.Count = List.length items
member this.Add newItem = newItem::(items |> List.filter ((<>) newItem)) |> RecentlyUsedList
![Page 141: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/141.jpg)
@theburningmonk
Affordancean affordance is a quality of an object, or
an environment, which allows an individual to perform an action. For example, a knob
affords twisting, and perhaps pushing, whilst a cord affords pulling.
![Page 143: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/143.jpg)
@theburningmonk
your abstractions should afford right behaviour,
whilst make it impossible to do the wrong thing
![Page 144: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/144.jpg)
@theburningmonk
“Make illegal states unrepresentable”
- Yaron Minsky
![Page 145: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/145.jpg)
@theburningmonk
discriminated unions
![Page 146: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/146.jpg)
@theburningmonk
type PaymentMethod = | Cash | Cheque of ChequeNumber | Card of CardType * CardNumber
finite, closed set of valid states ONLY
![Page 147: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/147.jpg)
closed hierarchy
![Page 148: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/148.jpg)
no Nulls
![Page 149: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/149.jpg)
@theburningmonk
match paymentMethod with | Cash -> … | Cheque chequeNum -> … | Card (cardType, cardNum) -> …
![Page 150: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/150.jpg)
@theburningmonk
Recap
![Page 151: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/151.jpg)
@theburningmonk
immutability
![Page 152: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/152.jpg)
@theburningmonk
make illegal state unrepresentable
![Page 153: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/153.jpg)
Getters and Setters
![Page 154: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/154.jpg)
“When it’s not necessary to change, it’s necessary to not change.”
- Lucius Cary
![Page 155: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/155.jpg)
“Now we have shortcuts to do the wrong thing.
We used to have type lots to do the wrong thing, not anymore.”
- Kevlin Henney
![Page 156: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/156.jpg)
@theburningmonk
immutability by default
![Page 157: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/157.jpg)
@theburningmonk
type Person = { Name : string Age : int }
![Page 158: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/158.jpg)
@theburningmonk
type Person = { mutable Name : string mutable Age : int }
![Page 159: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/159.jpg)
@theburningmonk
immutability
![Page 160: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/160.jpg)
Uncohesive Tests
![Page 161: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/161.jpg)
@theburningmonk
MethodA
MethodB
When_…Then_… ()When_…Then_… ()When_…Then_… ()When_…Then_… ()When_…Then_… ()When_…Then_… ()
![Page 162: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/162.jpg)
@theburningmonk
MethodA
MethodB
MethodC
FeatureA
FeatureB
![Page 163: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/163.jpg)
@theburningmonk
complexities & potential bugs in the way methods
work together
![Page 164: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/164.jpg)
@theburningmonk
…especially when states are concerned
![Page 165: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/165.jpg)
@theburningmonk
Test Driven Development
![Page 166: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/166.jpg)
“For tests to drive development they must do more than just test that code
performs its required functionality: they must clearly express that required
functionality to the reader. That is, they must be clear specification of the
required functionality.”
- Nat Pryce & Steve Freeman
![Page 167: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/167.jpg)
@theburningmonk
![Page 168: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/168.jpg)
@theburningmonk
how many tests?
![Page 169: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/169.jpg)
@theburningmonk
every test has a cost
![Page 170: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/170.jpg)
@theburningmonk
did we cover all the edge cases?
![Page 171: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/171.jpg)
@theburningmonk
Property-Based Testing(with FsCheck)
![Page 172: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/172.jpg)
@theburningmonk
List.rev
reverse + reverse = originallength of list is invariantappend + reverse = reverse + prepend
![Page 173: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/173.jpg)
@theburningmonk
List.revproperty : reverse + reverse = original
let ``reverse + reverse = original`` rev aList = aList |> rev |> rev = aList
Check.Quick (``reverse + reverse = original`` List.rev) // Ok, passed 100 tests.
![Page 174: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/174.jpg)
@theburningmonk
List.revproperty : length of list is invariant
let ``length of list is invariant`` rev aList = List.length (rev aList) = List.length aList
Check.Quick (``length of list is invariant`` List.rev) // Ok, passed 100 tests.
![Page 175: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/175.jpg)
@theburningmonk
List.revproperty : append + reverse = reverse + prepend
let ``append + reverse = reverse + prepend`` rev x aList = (aList @ [x]) |> rev = x::(aList |> rev)
Check.Quick (``append + reverse = reverse + prepend`` List.rev) // Ok, passed 100 tests.
![Page 176: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/176.jpg)
@theburningmonk
Check.Verbose (``append + reverse = reverse + prepend`` List.rev) // 0: ‘\005' [] 1: false ["N "] 2: “" [false; '{'] 3: ‘\017' [true; true; 'W'] 4: “" [""; false] 5: “yg]" [“H\nOq6"; null; false; false; '#'] 6: true [“"] … 11: <null> ['\014'; '0'; “\nRH”; "<#oe"; true; false; ‘O'] …
![Page 177: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/177.jpg)
@theburningmonk
shrinking
![Page 178: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/178.jpg)
@theburningmonk
Check.Quick (``append + reverse = reverse + prepend`` id) // Falsifiable, after 2 tests (4 shrinks) (StdGen (1855582125,296080469)):
Original:‘\013' ["}k"; ""; “"]
Shrunk:true [false]
![Page 179: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/179.jpg)
@theburningmonk
let computers do the grunt work
![Page 181: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/181.jpg)
@theburningmonk
Types vs Tests
![Page 182: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/182.jpg)
@theburningmonk
all bugs
![Page 183: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/183.jpg)
@theburningmonk
unknown
known
![Page 184: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/184.jpg)
@theburningmonk
tests
types
![Page 185: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/185.jpg)
@theburningmonk
tests
types
![Page 186: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/186.jpg)
@theburningmonk
unit-testing
distr. systemssystem-testing
![Page 187: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/187.jpg)
@theburningmonk
Jepsenproperty-based
unit-testing system-testing
distr. systems
![Page 188: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/188.jpg)
@theburningmonk
Jepsenproperty-based
unit-testing
types as proof TLA+
distr. systemssystem-testing
![Page 189: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/189.jpg)
Noisy CodeVisual DishonestyLego NamingUnderabstractionUnencapsulated StateGetters and SettersUncohesive Tests
![Page 190: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/190.jpg)
“Practice does not make perfect.Only perfect practice makes perfect.”
- Vince Lombardi
![Page 191: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/191.jpg)
“Perfection is not attainable. But if we chase perfection, we can catch excellence.”
- Vince Lombardi
![Page 192: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/192.jpg)
“Programming languages have a devious influence: they shape our thinking
habits.”
- Edsger W. Dijkstra
![Page 193: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/193.jpg)
“One of the most disastrous thing we can learn is the first programming language, even
if it's a good programming language.”
- Alan Kay
![Page 194: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/194.jpg)
“I’m not a great programmer; I’m just a good programmer
with great habits.”
- Kent Beck
![Page 195: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/195.jpg)
@theburningmonk
what about ineffective coding habits SOME F#/FP
programmers DO have?
![Page 196: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/196.jpg)
@theburningmonk
![Page 197: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/197.jpg)
@theburningmonk
people are too puritanical about purity
![Page 198: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/198.jpg)
…premature optimization is the root of all evil. Yet we should not pass up our opportunities in that
critical 3%
- Donald Knuth
![Page 199: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/199.jpg)
@theburningmonk
F# Map vs .Net array vs Dictionary
![Page 200: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/200.jpg)
@theburningmonk
![Page 201: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/201.jpg)
@theburningmonk
Explicit is better than implicit.
- the Zen of Python
![Page 202: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/202.jpg)
@theburningmonk
Simple is better than Complex.Complex is better than Complicated.
- the Zen of Python
![Page 203: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/203.jpg)
@theburningmonk
Special cases aren't special enough to break the rules.
- the Zen of Python
![Page 204: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/204.jpg)
@theburningmonk
Special cases aren't special enough to break the rules.
Although practicality beats purity.
- the Zen of Python
![Page 205: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/205.jpg)
@theburningmonk
If the implementation is hard to explain, it's a bad idea.
- the Zen of Python
![Page 206: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/206.jpg)
@theburningmonk
@theburningmonktheburningmonk.comgithub.com/theburningmonk
![Page 207: 7 ineffective coding habits many F# programmers don't have](https://reader030.vdocuments.mx/reader030/viewer/2022033018/586e73d51a28ab99598b5631/html5/thumbnails/207.jpg)
@theburningmonk
is hiring :-)http://tech.just-eat.com/jobs