Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
7 ineffective
coding
habits
MANY
F#
programmers
DON’T
have
BuildStuff ‘14
habit
ˈhabɪt/
A settled or regular tendency
or practice, especially one
that is hard to give up.
“I’m not a great programmer;
I’m just a good programmer
with great habits.”
- Kent Beck
Noisy Code
Visual Dishonesty
Lego Naming
Underabstraction
Unencapsulated State
Getters and Setters
Uncohesive Tests
@theburningmonk
does the language I use
make a difference?
“Programming languages
have a devious influence:
they shape our thinking
habits.”
- Edsger W. Dijkstra
Noisy Code
@theburningmonk
@theburningmonk
@theburningmonk
every LOC is a cost
@theburningmonk
more code
more chance for bugs
@theburningmonk
more code
more engineers
@theburningmonk
@theburningmonk
You should do whatever possible to increase the
productivity of individual programmers in terms of
the exp...
@theburningmonk
You should do whatever possible to increase the
productivity of individual programmers in terms of
the exp...
does the language I use
make a difference?
@theburningmonk
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
source http://bit.ly/1oBHHh1
@theburningmonk
Recap
@theburningmonk
no { }
no nulls
fewer syntactic noise
@theburningmonk
fewer code
fewer noise
@theburningmonk
fewer noise
higher SNR
@theburningmonk
fewer code
more productivity
- Dan North
“Lead time to someone saying
thank you is the only reputation
metric that matters.”
Visual
Dishonesty
“…a clean design is one that
supports visual thinking so
people can meet their
informational needs with a
minimum of consc...
@theburningmonk
public void MyCleverMethod(
int firstArg,
string secondArg)
signifies hierarchy
“You convey information by the way you
arrange a design’s elements in relation to
each other. This information is understo...
“This is great if the visual relationships are
obvious and accurate, but if they’re not,
your audience is going to get con...
@theburningmonk
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage
problem us...
@theburningmonk
Whilst talking with an ex-colleague, a question came up on how to implement the Stable Marriage
problem us...
@theburningmonk
how we read CODE
public void DoSomething(int x, int y)
{
Foo(y,
Bar(x,
Zoo(Monkey())));
}
see also http://...
@theburningmonk
how we read CODE
public void DoSomething(int x, int y)
{
Foo(y,
Bar(x,
Zoo(Monkey())));
}
2.bottom-to-top
...
@theburningmonk
Whilst talking with an ex-colleague, a question came up on
how to implement the Stable Marriage problem us...
@theburningmonk
|>
see also http://bit.ly/1KN8cd0
@theburningmonk
how we read CODE
let drawCircle x y radius =
circle radius
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move...
@theburningmonk
how we read CODE
let drawCircle x y radius =
circle radius
|> filled (rgb 150 170 150)
|> alpha 0.5
|> move...
@theburningmonk
{}
@theburningmonk
public ResultType MyCleverMethod(
int firstArg,
string secondArg,
string thirdArg) {
var localVar =
Anothe...
@theburningmonk
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXX
XXX XXXXXXXX
XXXXXX XXXXXXXXX
XXXXXX XXXXXXXX
XXX XXXXXXXX
XXXXXXXXXXXXXX...
@theburningmonk
public ResultType MyCleverMethod(
int firstArg,
string secondArg,
string thirdArg) {
var localVar =
Anothe...
“This is great if the visual relationships are
obvious and accurate, but if they’re not,
your audience is going to get con...
@theburningmonk
public ResultType MyCleverMethod(
int firstArg,
string secondArg,
string thirdArg)
{
var localVar =
Anothe...
@theburningmonk
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXX
XXX XXXXXXXX
XXXXXX XXXXXXXXX
XXXXXX XXXXXXXX
XXX XXXXXXXX
XXXXXXXXXXXXXX...
- Douglas Crockford
“It turns out that style
matters in programming for
the same reason that it
matters in writing.
It mak...
@theburningmonk
two competing rules for
structuring code in
C-style languages
@theburningmonk
Compiler
{ }
Human
{ } + whitespace
@theburningmonk
what if…?
@theburningmonk
Compiler
whitespace
Human
whitespace
@theburningmonk
xxx
{
}
xxx {
}
no
braces no
problem
@theburningmonk
There should be one - and preferably only
one - obvious way to do it.
- the Zen of Python
@theburningmonk
let myCleverFunction x y z =
let localVar = anotherCleverFunction x y
if localVar.IsSomething(z, MY_CONSTA...
@theburningmonk
XXX XXXXXXXXXXXXXXXX X X X
XXX XXXXXXXX XXXXXXXXXXXXXXXXXXXX X X
XX XXXXXXXX XXXXXXXXXXX X XXXXXXXXXX XXXX...
@theburningmonk
You should do whatever possible to increase the
productivity of individual programmers in terms of
the exp...
@theburningmonk
Recap
@theburningmonk
|>
@theburningmonk
one way to describe
hierarchy
Lego Naming
@theburningmonk
naming is HARD
- Phil Karlton
“There are only two hard things
in Computer Science: cache
invalidation and naming things.”
- Mike Mahemoff
“Names are the one and only
tool you have to explain what a
variable does in every place it
appears, witho...
@theburningmonk
Lego Naming
Gluing common words together in an
attempt to create meaning.
@theburningmonk
Strategy
Process
Create
Add
Controller
Factory
Proxy
Object
Exception
Enable
Do
Disable
Service
Remove
Che...
@theburningmonk
see http://methodnamer.com
@theburningmonk
this is not naming
@theburningmonk
this is not naming
this is labelling
@theburningmonk
@theburningmonk
@theburningmonk
naming is HARD
@theburningmonk
anonymous functions
aka lambdas
@theburningmonk
fewer things to name
@theburningmonk
words
|> Array.map (fun x -> x.Count)
|> Array.reduce (+)
@theburningmonk
smaller scope
shorter names
@theburningmonk
@theburningmonk
http://bit.ly/1ZpAByu
When x, y, and z are
great variable names
@theburningmonk
"The length of a name should be related to the
length of the scope. You can use very short
variable names ...
@theburningmonk
object expressions
@theburningmonk
enterpriseCrew.OrderBy(
(fun c -> c.Current),
{ new IComparer<Occupation> with
member this.Compare(x, y) =...
@theburningmonk
enterpriseCrew.OrderBy(
(fun c -> c.Current),
{ new IComparer<Occupation> with
member this.Compare(x, y) =...
@theburningmonk
fewer things to name
@theburningmonk
tuples + pattern matching
@theburningmonk
tuples + pattern matching
fewer abstractions
@theburningmonk
tuples + pattern matching
fewer abstractions
fewer things to name
@theburningmonk
words
|> Seq.groupBy id
|> Seq.map (fun (word, gr) ->
word, Seq.length gr)
|> Seq.iter (fun (word, len) ->...
@theburningmonk
words
|> Seq.groupBy id
|> Seq.map (fun (word, gr) ->
word, Seq.length gr)
|> Seq.iter (fun (word, len) ->...
@theburningmonk
words
|> Seq.groupBy id
|> Seq.map (fun (word, gr) ->
word, Seq.length gr)
|> Seq.iter (fun (word, len) ->...
@theburningmonk
words
|> Seq.groupBy id
|> Seq.map (fun (word, gr) ->
word, Seq.length gr)
|> Seq.iter (fun (word, len) ->...
@theburningmonk
Lego Naming can also be
the symptom of a failure to
identify the right level of
abstractions.
@theburningmonk
the RIGHT level of
abstraction might be
smaller than “object”
@theburningmonk
public interface ConditionChecker
{
bool CheckCondition();
}
@theburningmonk
public interface Condition
{
bool IsTrue();
}
@theburningmonk
@theburningmonk
type Condition = unit -> bool
source https://vimeo.com/113588389
@theburningmonk
ClassNotFoundException
IllegalArgumentException
IndexOutOfBoundsException
NoSuchMethodException
Unsupporte...
@theburningmonk
ClassNotFound
IllegalArgument
IndexOutOfBounds
NoSuchMethod
UnsupportedOperation
@theburningmonk
ArithmeticException
ArrayStoreException
ClassCastException
InstantiationException
NullPointerException
Sec...
@theburningmonk
IntegerDivisionByZero
IllegalArrayElementType
CastToNonSubclass
ClassCannotBeInstantiated
NullDereferenced...
@theburningmonk
lightweight exception syntax
@theburningmonk
open System
open System.IO
exception InsufficientBytes
@theburningmonk
open System
open System.IO
exception InsufficientBytes
what could this type represent?
@theburningmonk
Recap
@theburningmonk
F# < > silver bullet
@theburningmonk
anonymous functions
fewer things to name
@theburningmonk
short names
@theburningmonk
tuple + pattern matching
fewer things to name
@theburningmonk
no abstraction is too small
@theburningmonk
lightweight exception syntax
Underabstraction
@theburningmonk
@theburningmonk
public Result DoSomething(
int a,
string b,
string c,
string d,
DateTime e,
DateTime f,
string g,
MyEnum h)
“If you have a procedure
with ten parameters, you
probably missed some.”
- Alan Perlis
source https://vimeo.com/97507575
@theburningmonk
lightweight syntax for
types and hierarchies
@theburningmonk
record
@theburningmonk
type Employee =
{
FirstName : string
Surname : string
Salary : int<Pound>
}
@theburningmonk
type Employee =
{
FirstName : string
Surname : string
Salary : int<Pound>
}
immutable by default
@theburningmonk
let promote emp raise =
{
emp with Salary <- emp.Salary + raise
}
@theburningmonk
mutable state
complects
value and time
@theburningmonk
type Employee =
{
FirstName : string
Surname : string
Salary : int<Pound>
}
unit-of-measure
@theburningmonk
[<Measure>]
type Pound
e.g. 42<Pound>
153<Pound>
10<Meter> / 2<Second> = 5<Meter/Second>
10<Meter> * 2<Second> = 20<Meter Second>
10<Meter> + 10<Meter> = 20<Meter>
10<Mete...
10<Meter> / 2<Second> = 5<Meter/Second>
10<Meter> * 2<Second> = 20<Meter Second>
10<Meter> + 10<Meter> = 20<Meter>
10<Mete...
@theburningmonk
discriminated
unions
@theburningmonk
type PaymentMethod =
| Cash
| Cheque of ChequeNumber
| Card of CardType * CardNumber
Unencapsulated
State
@theburningmonk
@theburningmonk
public class RecentlyUsedList
{
private List<string> items = new List<string>();
public List<string> Items...
@theburningmonk
immutability
@theburningmonk
type RecentlyUsedList (?items) =
let items = defaultArg items [ ]
member this.Items = Array.ofList items
m...
@theburningmonk
Affordance
an affordance is a quality of an object, or
an environment, which allows an individual
to perfo...
source https://www.youtube.com/watch?v=aAb7hSCtvGw
@theburningmonk
your abstractions should
afford right behaviour,
whilst make it impossible
to do the wrong thing
@theburningmonk
“Make illegal states unrepresentable”
- Yaron Minsky
@theburningmonk
discriminated
unions
@theburningmonk
type PaymentMethod =
| Cash
| Cheque of ChequeNumber
| Card of CardType * CardNumber
finite, closed set of...
closed hierarchy
no Nulls
@theburningmonk
match paymentMethod with
| Cash -> …
| Cheque chequeNum -> …
| Card (cardType, cardNum) -> …
@theburningmonk
Recap
@theburningmonk
immutability
@theburningmonk
make illegal state
unrepresentable
Getters and
Setters
“When it’s not necessary to change,
it’s necessary to not change.”
- Lucius Cary
“Now we have shortcuts to do the
wrong thing.
We used to have type lots to do the
wrong thing, not anymore.”
- Kevlin Henn...
@theburningmonk
immutability by default
@theburningmonk
type Person =
{
Name : string
Age : int
}
@theburningmonk
type Person =
{
mutable Name : string
mutable Age : int
}
@theburningmonk
immutability
Uncohesive
Tests
@theburningmonk
MethodA
MethodB
When_…Then_… ()
When_…Then_… ()
When_…Then_… ()
When_…Then_… ()
When_…Then_… ()
When_…Then...
@theburningmonk
MethodA
MethodB
MethodC
FeatureA
FeatureB
@theburningmonk
complexities & potential
bugs in the way methods
work together
@theburningmonk
…especially when states
are concerned
@theburningmonk
Test Driven Development
“For tests to drive development they
must do more than just test that code
performs its required functionality: they
must ...
@theburningmonk
@theburningmonk
how many tests?
@theburningmonk
every test has a cost
@theburningmonk
did we cover all the
edge cases?
@theburningmonk
Property-Based Testing
(with FsCheck)
@theburningmonk
List.rev
reverse + reverse = original
length of list is invariant
append + reverse = reverse + prepend
@theburningmonk
List.rev
property : reverse + reverse = original
let ``reverse + reverse = original`` rev aList =
aList |>...
@theburningmonk
List.rev
property : length of list is invariant
let ``length of list is invariant`` rev aList =
List.lengt...
@theburningmonk
List.rev
property : append + reverse = reverse + prepend
let ``append + reverse = reverse + prepend`` rev ...
@theburningmonk
Check.Verbose (``append + reverse = reverse + prepend``
List.rev)
//
0: ‘005' []
1: false ["N "]
2: “" [fa...
@theburningmonk
shrinking
@theburningmonk
Check.Quick (``append + reverse = reverse + prepend`` id)
// Falsifiable, after 2 tests (4 shrinks) (StdGe...
@theburningmonk
let computers do the
grunt work
source : http://bit.ly/1kEpEso
@theburningmonk
Types vs Tests
@theburningmonk
all bugs
@theburningmonk
unknown
known
@theburningmonk
tests
types
@theburningmonk
tests
types
@theburningmonk
unit-testing
distr. systems
system-testing
@theburningmonk
Jepsenproperty-based
unit-testing system-testing
distr. systems
@theburningmonk
Jepsenproperty-based
unit-testing
types as proof TLA+
distr. systems
system-testing
Noisy Code
Visual Dishonesty
Lego Naming
Underabstraction
Unencapsulated State
Getters and Setters
Uncohesive Tests
“Practice does not make perfect.
Only perfect practice makes perfect.”
- Vince Lombardi
“Perfection is not attainable. But if we
chase perfection, we can catch excellence.”
- Vince Lombardi
“Programming languages
have a devious influence:
they shape our thinking
habits.”
- Edsger W. Dijkstra
“One of the most disastrous
thing we can learn is the first
programming language, even
if it's a good programming
language....
“I’m not a great programmer;
I’m just a good programmer
with great habits.”
- Kent Beck
@theburningmonk
what about ineffective
coding habits SOME F#/FP
programmers DO have?
@theburningmonk
@theburningmonk
people are too puritanical about purity
…premature optimization
is the root of all evil. Yet
we should not pass up
our opportunities in that
critical 3%
- Donald ...
@theburningmonk
F# Map vs .Net array vs Dictionary
@theburningmonk
@theburningmonk
Explicit is better than implicit.
- the Zen of Python
@theburningmonk
Simple is better than Complex.
Complex is better than Complicated.
- the Zen of Python
@theburningmonk
Special cases aren't special enough to
break the rules.
- the Zen of Python
@theburningmonk
Special cases aren't special enough to
break the rules.
Although practicality beats purity.
- the Zen of P...
@theburningmonk
If the implementation is hard to explain,
it's a bad idea.
- the Zen of Python
@theburningmonk
@theburningmonk
theburningmonk.com
github.com/theburningmonk
@theburningmonk
is hiring :-)
http://tech.just-eat.com/jobs
7 ineffective coding habits many F# programmers don't have
7 ineffective coding habits many F# programmers don't have
7 ineffective coding habits many F# programmers don't have
Upcoming SlideShare
Loading in …5
×

of

7 ineffective coding habits many F# programmers don't have Slide 1 7 ineffective coding habits many F# programmers don't have Slide 2 7 ineffective coding habits many F# programmers don't have Slide 3 7 ineffective coding habits many F# programmers don't have Slide 4 7 ineffective coding habits many F# programmers don't have Slide 5 7 ineffective coding habits many F# programmers don't have Slide 6 7 ineffective coding habits many F# programmers don't have Slide 7 7 ineffective coding habits many F# programmers don't have Slide 8 7 ineffective coding habits many F# programmers don't have Slide 9 7 ineffective coding habits many F# programmers don't have Slide 10 7 ineffective coding habits many F# programmers don't have Slide 11 7 ineffective coding habits many F# programmers don't have Slide 12 7 ineffective coding habits many F# programmers don't have Slide 13 7 ineffective coding habits many F# programmers don't have Slide 14 7 ineffective coding habits many F# programmers don't have Slide 15 7 ineffective coding habits many F# programmers don't have Slide 16 7 ineffective coding habits many F# programmers don't have Slide 17 7 ineffective coding habits many F# programmers don't have Slide 18 7 ineffective coding habits many F# programmers don't have Slide 19 7 ineffective coding habits many F# programmers don't have Slide 20 7 ineffective coding habits many F# programmers don't have Slide 21 7 ineffective coding habits many F# programmers don't have Slide 22 7 ineffective coding habits many F# programmers don't have Slide 23 7 ineffective coding habits many F# programmers don't have Slide 24 7 ineffective coding habits many F# programmers don't have Slide 25 7 ineffective coding habits many F# programmers don't have Slide 26 7 ineffective coding habits many F# programmers don't have Slide 27 7 ineffective coding habits many F# programmers don't have Slide 28 7 ineffective coding habits many F# programmers don't have Slide 29 7 ineffective coding habits many F# programmers don't have Slide 30 7 ineffective coding habits many F# programmers don't have Slide 31 7 ineffective coding habits many F# programmers don't have Slide 32 7 ineffective coding habits many F# programmers don't have Slide 33 7 ineffective coding habits many F# programmers don't have Slide 34 7 ineffective coding habits many F# programmers don't have Slide 35 7 ineffective coding habits many F# programmers don't have Slide 36 7 ineffective coding habits many F# programmers don't have Slide 37 7 ineffective coding habits many F# programmers don't have Slide 38 7 ineffective coding habits many F# programmers don't have Slide 39 7 ineffective coding habits many F# programmers don't have Slide 40 7 ineffective coding habits many F# programmers don't have Slide 41 7 ineffective coding habits many F# programmers don't have Slide 42 7 ineffective coding habits many F# programmers don't have Slide 43 7 ineffective coding habits many F# programmers don't have Slide 44 7 ineffective coding habits many F# programmers don't have Slide 45 7 ineffective coding habits many F# programmers don't have Slide 46 7 ineffective coding habits many F# programmers don't have Slide 47 7 ineffective coding habits many F# programmers don't have Slide 48 7 ineffective coding habits many F# programmers don't have Slide 49 7 ineffective coding habits many F# programmers don't have Slide 50 7 ineffective coding habits many F# programmers don't have Slide 51 7 ineffective coding habits many F# programmers don't have Slide 52 7 ineffective coding habits many F# programmers don't have Slide 53 7 ineffective coding habits many F# programmers don't have Slide 54 7 ineffective coding habits many F# programmers don't have Slide 55 7 ineffective coding habits many F# programmers don't have Slide 56 7 ineffective coding habits many F# programmers don't have Slide 57 7 ineffective coding habits many F# programmers don't have Slide 58 7 ineffective coding habits many F# programmers don't have Slide 59 7 ineffective coding habits many F# programmers don't have Slide 60 7 ineffective coding habits many F# programmers don't have Slide 61 7 ineffective coding habits many F# programmers don't have Slide 62 7 ineffective coding habits many F# programmers don't have Slide 63 7 ineffective coding habits many F# programmers don't have Slide 64 7 ineffective coding habits many F# programmers don't have Slide 65 7 ineffective coding habits many F# programmers don't have Slide 66 7 ineffective coding habits many F# programmers don't have Slide 67 7 ineffective coding habits many F# programmers don't have Slide 68 7 ineffective coding habits many F# programmers don't have Slide 69 7 ineffective coding habits many F# programmers don't have Slide 70 7 ineffective coding habits many F# programmers don't have Slide 71 7 ineffective coding habits many F# programmers don't have Slide 72 7 ineffective coding habits many F# programmers don't have Slide 73 7 ineffective coding habits many F# programmers don't have Slide 74 7 ineffective coding habits many F# programmers don't have Slide 75 7 ineffective coding habits many F# programmers don't have Slide 76 7 ineffective coding habits many F# programmers don't have Slide 77 7 ineffective coding habits many F# programmers don't have Slide 78 7 ineffective coding habits many F# programmers don't have Slide 79 7 ineffective coding habits many F# programmers don't have Slide 80 7 ineffective coding habits many F# programmers don't have Slide 81 7 ineffective coding habits many F# programmers don't have Slide 82 7 ineffective coding habits many F# programmers don't have Slide 83 7 ineffective coding habits many F# programmers don't have Slide 84 7 ineffective coding habits many F# programmers don't have Slide 85 7 ineffective coding habits many F# programmers don't have Slide 86 7 ineffective coding habits many F# programmers don't have Slide 87 7 ineffective coding habits many F# programmers don't have Slide 88 7 ineffective coding habits many F# programmers don't have Slide 89 7 ineffective coding habits many F# programmers don't have Slide 90 7 ineffective coding habits many F# programmers don't have Slide 91 7 ineffective coding habits many F# programmers don't have Slide 92 7 ineffective coding habits many F# programmers don't have Slide 93 7 ineffective coding habits many F# programmers don't have Slide 94 7 ineffective coding habits many F# programmers don't have Slide 95 7 ineffective coding habits many F# programmers don't have Slide 96 7 ineffective coding habits many F# programmers don't have Slide 97 7 ineffective coding habits many F# programmers don't have Slide 98 7 ineffective coding habits many F# programmers don't have Slide 99 7 ineffective coding habits many F# programmers don't have Slide 100 7 ineffective coding habits many F# programmers don't have Slide 101 7 ineffective coding habits many F# programmers don't have Slide 102 7 ineffective coding habits many F# programmers don't have Slide 103 7 ineffective coding habits many F# programmers don't have Slide 104 7 ineffective coding habits many F# programmers don't have Slide 105 7 ineffective coding habits many F# programmers don't have Slide 106 7 ineffective coding habits many F# programmers don't have Slide 107 7 ineffective coding habits many F# programmers don't have Slide 108 7 ineffective coding habits many F# programmers don't have Slide 109 7 ineffective coding habits many F# programmers don't have Slide 110 7 ineffective coding habits many F# programmers don't have Slide 111 7 ineffective coding habits many F# programmers don't have Slide 112 7 ineffective coding habits many F# programmers don't have Slide 113 7 ineffective coding habits many F# programmers don't have Slide 114 7 ineffective coding habits many F# programmers don't have Slide 115 7 ineffective coding habits many F# programmers don't have Slide 116 7 ineffective coding habits many F# programmers don't have Slide 117 7 ineffective coding habits many F# programmers don't have Slide 118 7 ineffective coding habits many F# programmers don't have Slide 119 7 ineffective coding habits many F# programmers don't have Slide 120 7 ineffective coding habits many F# programmers don't have Slide 121 7 ineffective coding habits many F# programmers don't have Slide 122 7 ineffective coding habits many F# programmers don't have Slide 123 7 ineffective coding habits many F# programmers don't have Slide 124 7 ineffective coding habits many F# programmers don't have Slide 125 7 ineffective coding habits many F# programmers don't have Slide 126 7 ineffective coding habits many F# programmers don't have Slide 127 7 ineffective coding habits many F# programmers don't have Slide 128 7 ineffective coding habits many F# programmers don't have Slide 129 7 ineffective coding habits many F# programmers don't have Slide 130 7 ineffective coding habits many F# programmers don't have Slide 131 7 ineffective coding habits many F# programmers don't have Slide 132 7 ineffective coding habits many F# programmers don't have Slide 133 7 ineffective coding habits many F# programmers don't have Slide 134 7 ineffective coding habits many F# programmers don't have Slide 135 7 ineffective coding habits many F# programmers don't have Slide 136 7 ineffective coding habits many F# programmers don't have Slide 137 7 ineffective coding habits many F# programmers don't have Slide 138 7 ineffective coding habits many F# programmers don't have Slide 139 7 ineffective coding habits many F# programmers don't have Slide 140 7 ineffective coding habits many F# programmers don't have Slide 141 7 ineffective coding habits many F# programmers don't have Slide 142 7 ineffective coding habits many F# programmers don't have Slide 143 7 ineffective coding habits many F# programmers don't have Slide 144 7 ineffective coding habits many F# programmers don't have Slide 145 7 ineffective coding habits many F# programmers don't have Slide 146 7 ineffective coding habits many F# programmers don't have Slide 147 7 ineffective coding habits many F# programmers don't have Slide 148 7 ineffective coding habits many F# programmers don't have Slide 149 7 ineffective coding habits many F# programmers don't have Slide 150 7 ineffective coding habits many F# programmers don't have Slide 151 7 ineffective coding habits many F# programmers don't have Slide 152 7 ineffective coding habits many F# programmers don't have Slide 153 7 ineffective coding habits many F# programmers don't have Slide 154 7 ineffective coding habits many F# programmers don't have Slide 155 7 ineffective coding habits many F# programmers don't have Slide 156 7 ineffective coding habits many F# programmers don't have Slide 157 7 ineffective coding habits many F# programmers don't have Slide 158 7 ineffective coding habits many F# programmers don't have Slide 159 7 ineffective coding habits many F# programmers don't have Slide 160 7 ineffective coding habits many F# programmers don't have Slide 161 7 ineffective coding habits many F# programmers don't have Slide 162 7 ineffective coding habits many F# programmers don't have Slide 163 7 ineffective coding habits many F# programmers don't have Slide 164 7 ineffective coding habits many F# programmers don't have Slide 165 7 ineffective coding habits many F# programmers don't have Slide 166 7 ineffective coding habits many F# programmers don't have Slide 167 7 ineffective coding habits many F# programmers don't have Slide 168 7 ineffective coding habits many F# programmers don't have Slide 169 7 ineffective coding habits many F# programmers don't have Slide 170 7 ineffective coding habits many F# programmers don't have Slide 171 7 ineffective coding habits many F# programmers don't have Slide 172 7 ineffective coding habits many F# programmers don't have Slide 173 7 ineffective coding habits many F# programmers don't have Slide 174 7 ineffective coding habits many F# programmers don't have Slide 175 7 ineffective coding habits many F# programmers don't have Slide 176 7 ineffective coding habits many F# programmers don't have Slide 177 7 ineffective coding habits many F# programmers don't have Slide 178 7 ineffective coding habits many F# programmers don't have Slide 179 7 ineffective coding habits many F# programmers don't have Slide 180 7 ineffective coding habits many F# programmers don't have Slide 181 7 ineffective coding habits many F# programmers don't have Slide 182 7 ineffective coding habits many F# programmers don't have Slide 183 7 ineffective coding habits many F# programmers don't have Slide 184 7 ineffective coding habits many F# programmers don't have Slide 185 7 ineffective coding habits many F# programmers don't have Slide 186 7 ineffective coding habits many F# programmers don't have Slide 187 7 ineffective coding habits many F# programmers don't have Slide 188 7 ineffective coding habits many F# programmers don't have Slide 189 7 ineffective coding habits many F# programmers don't have Slide 190 7 ineffective coding habits many F# programmers don't have Slide 191 7 ineffective coding habits many F# programmers don't have Slide 192 7 ineffective coding habits many F# programmers don't have Slide 193 7 ineffective coding habits many F# programmers don't have Slide 194 7 ineffective coding habits many F# programmers don't have Slide 195 7 ineffective coding habits many F# programmers don't have Slide 196 7 ineffective coding habits many F# programmers don't have Slide 197 7 ineffective coding habits many F# programmers don't have Slide 198 7 ineffective coding habits many F# programmers don't have Slide 199 7 ineffective coding habits many F# programmers don't have Slide 200 7 ineffective coding habits many F# programmers don't have Slide 201 7 ineffective coding habits many F# programmers don't have Slide 202 7 ineffective coding habits many F# programmers don't have Slide 203 7 ineffective coding habits many F# programmers don't have Slide 204 7 ineffective coding habits many F# programmers don't have Slide 205 7 ineffective coding habits many F# programmers don't have Slide 206 7 ineffective coding habits many F# programmers don't have Slide 207
Upcoming SlideShare
CSS Grid Layout
Next
Download to read offline and view in fullscreen.

181 Likes

Share

Download to read offline

7 ineffective coding habits many F# programmers don't have

Download to read offline

At BuildStuff'14, Kevlin Henney presented an excellent talk titled "Seven ineffective coding habits of many programmers". As an attendee that day and someone who has exhibited many of these habits over the years, I came to realize that using F# has cured me of many of these ineffective habits! In this talk I'll share my thoughts on how the use of F# and functional programming techniques can help form and nurture good habits and give you the perfect practice you need to make perfect.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

7 ineffective coding habits many F# programmers don't have

  1. 7 ineffective coding habits MANY F# programmers DON’T have
  2. BuildStuff ‘14
  3. habit ˈhabɪt/ A settled or regular tendency or practice, especially one that is hard to give up.
  4. “I’m not a great programmer; I’m just a good programmer with great habits.” - Kent Beck
  5. Noisy Code Visual Dishonesty Lego Naming Underabstraction Unencapsulated State Getters and Setters Uncohesive Tests
  6. @theburningmonk does the language I use make a difference?
  7. “Programming languages have a devious influence: they shape our thinking habits.” - Edsger W. Dijkstra
  8. Noisy Code
  9. @theburningmonk
  10. @theburningmonk
  11. @theburningmonk every LOC is a cost
  12. @theburningmonk more code more chance for bugs
  13. @theburningmonk more code more engineers
  14. @theburningmonk
  15. @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.
  16. @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.
  17. does the language I use make a difference?
  18. @theburningmonk
  19. @theburningmonk source http://bit.ly/1oBHHh1
  20. @theburningmonk source http://bit.ly/1oBHHh1
  21. @theburningmonk source http://bit.ly/1oBHHh1
  22. @theburningmonk source http://bit.ly/1oBHHh1
  23. @theburningmonk source http://bit.ly/1oBHHh1
  24. @theburningmonk source http://bit.ly/1oBHHh1
  25. @theburningmonk source http://bit.ly/1oBHHh1
  26. @theburningmonk Recap
  27. @theburningmonk no { } no nulls fewer syntactic noise
  28. @theburningmonk fewer code fewer noise
  29. @theburningmonk fewer noise higher SNR
  30. @theburningmonk fewer code more productivity
  31. - Dan North “Lead time to someone saying thank you is the only reputation metric that matters.”
  32. Visual Dishonesty
  33. “…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)
  34. @theburningmonk public void MyCleverMethod( int firstArg, string secondArg) signifies hierarchy
  35. “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)
  36. “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)
  37. @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 experiment In terms of interaction between the different modules, I imagined something along the lines of… how we read ENGLISH see also http://bit.ly/1KN8cd0
  38. @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 experiment In 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 see also http://bit.ly/1KN8cd0
  39. @theburningmonk how we read CODE public void DoSomething(int x, int y) { Foo(y, Bar(x, Zoo(Monkey()))); } see also http://bit.ly/1KN8cd0
  40. @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
  41. @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 experiment In 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
  42. @theburningmonk |> see also http://bit.ly/1KN8cd0
  43. @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
  44. @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-bottom 1.left-to-right see also http://bit.ly/1KN8cd0
  45. @theburningmonk {}
  46. @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(); }
  47. @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
  48. @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(); }
  49. “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.”
  50. @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(); }
  51. @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
  52. - Douglas Crockford “It turns out that style matters in programming for the same reason that it matters in writing. It makes for better reading.”
  53. @theburningmonk two competing rules for structuring code in C-style languages
  54. @theburningmonk Compiler { } Human { } + whitespace
  55. @theburningmonk what if…?
  56. @theburningmonk Compiler whitespace Human whitespace
  57. @theburningmonk xxx { } xxx { } no braces no problem
  58. @theburningmonk There should be one - and preferably only one - obvious way to do it. - the Zen of Python
  59. @theburningmonk let myCleverFunction x y z = let localVar = anotherCleverFunction x y if localVar.IsSomething(z, MY_CONSTANT) then doSomething localVar localVar.GetSomething()
  60. @theburningmonk XXX XXXXXXXXXXXXXXXX X X X XXX XXXXXXXX XXXXXXXXXXXXXXXXXXXX X X XX XXXXXXXX XXXXXXXXXXX X XXXXXXXXXX XXXX XXXXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXXX
  61. @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.
  62. @theburningmonk Recap
  63. @theburningmonk |>
  64. @theburningmonk one way to describe hierarchy
  65. Lego Naming
  66. @theburningmonk naming is HARD
  67. - Phil Karlton “There are only two hard things in Computer Science: cache invalidation and naming things.”
  68. - 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.”
  69. @theburningmonk Lego Naming Gluing common words together in an attempt to create meaning.
  70. @theburningmonk Strategy Process Create Add Controller Factory Proxy Object Exception Enable Do Disable Service Remove Check Get Set Update Validate
  71. @theburningmonk see http://methodnamer.com
  72. @theburningmonk this is not naming
  73. @theburningmonk this is not naming this is labelling
  74. @theburningmonk
  75. @theburningmonk
  76. @theburningmonk naming is HARD
  77. @theburningmonk anonymous functions aka lambdas
  78. @theburningmonk fewer things to name
  79. @theburningmonk words |> Array.map (fun x -> x.Count) |> Array.reduce (+)
  80. @theburningmonk smaller scope shorter names
  81. @theburningmonk
  82. @theburningmonk http://bit.ly/1ZpAByu When x, y, and z are great variable names
  83. @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
  84. @theburningmonk object expressions
  85. @theburningmonk enterpriseCrew.OrderBy( (fun c -> c.Current), { new IComparer<Occupation> with member this.Compare(x, y) = x.Position.CompareTo(y.Position) })
  86. @theburningmonk enterpriseCrew.OrderBy( (fun c -> c.Current), { new IComparer<Occupation> with member this.Compare(x, y) = x.Position.CompareTo(y.Position) })
  87. @theburningmonk fewer things to name
  88. @theburningmonk tuples + pattern matching
  89. @theburningmonk tuples + pattern matching fewer abstractions
  90. @theburningmonk tuples + pattern matching fewer abstractions fewer things to name
  91. @theburningmonk words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
  92. @theburningmonk words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
  93. @theburningmonk words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
  94. @theburningmonk words |> Seq.groupBy id |> Seq.map (fun (word, gr) -> word, Seq.length gr) |> Seq.iter (fun (word, len) -> printfn “%s - %s” word len)
  95. @theburningmonk Lego Naming can also be the symptom of a failure to identify the right level of abstractions.
  96. @theburningmonk the RIGHT level of abstraction might be smaller than “object”
  97. @theburningmonk public interface ConditionChecker { bool CheckCondition(); }
  98. @theburningmonk public interface Condition { bool IsTrue(); }
  99. @theburningmonk
  100. @theburningmonk type Condition = unit -> bool
  101. source https://vimeo.com/113588389
  102. @theburningmonk ClassNotFoundException IllegalArgumentException IndexOutOfBoundsException NoSuchMethodException UnsupportedOperationException
  103. @theburningmonk ClassNotFound IllegalArgument IndexOutOfBounds NoSuchMethod UnsupportedOperation
  104. @theburningmonk ArithmeticException ArrayStoreException ClassCastException InstantiationException NullPointerException SecurityException
  105. @theburningmonk IntegerDivisionByZero IllegalArrayElementType CastToNonSubclass ClassCannotBeInstantiated NullDereferenced SecurityViolation
  106. @theburningmonk lightweight exception syntax
  107. @theburningmonk open System open System.IO exception InsufficientBytes
  108. @theburningmonk open System open System.IO exception InsufficientBytes what could this type represent?
  109. @theburningmonk Recap
  110. @theburningmonk F# < > silver bullet
  111. @theburningmonk anonymous functions fewer things to name
  112. @theburningmonk short names
  113. @theburningmonk tuple + pattern matching fewer things to name
  114. @theburningmonk no abstraction is too small
  115. @theburningmonk lightweight exception syntax
  116. Underabstraction
  117. @theburningmonk
  118. @theburningmonk public Result DoSomething( int a, string b, string c, string d, DateTime e, DateTime f, string g, MyEnum h)
  119. “If you have a procedure with ten parameters, you probably missed some.” - Alan Perlis
  120. source https://vimeo.com/97507575
  121. @theburningmonk lightweight syntax for types and hierarchies
  122. @theburningmonk record
  123. @theburningmonk type Employee = { FirstName : string Surname : string Salary : int<Pound> }
  124. @theburningmonk type Employee = { FirstName : string Surname : string Salary : int<Pound> } immutable by default
  125. @theburningmonk let promote emp raise = { emp with Salary <- emp.Salary + raise }
  126. @theburningmonk mutable state complects value and time
  127. @theburningmonk type Employee = { FirstName : string Surname : string Salary : int<Pound> } unit-of-measure
  128. @theburningmonk [<Measure>] type Pound e.g. 42<Pound> 153<Pound>
  129. 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> // error 10<Meter> + 2 // error
  130. 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> // error 10<Meter> + 2 // error
  131. @theburningmonk discriminated unions
  132. @theburningmonk type PaymentMethod = | Cash | Cheque of ChequeNumber | Card of CardType * CardNumber
  133. Unencapsulated State
  134. @theburningmonk
  135. @theburningmonk public class RecentlyUsedList { private List<string> items = new List<string>(); public List<string> Items { get { return items; } } … }
  136. @theburningmonk immutability
  137. @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
  138. @theburningmonk Affordance an 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.
  139. source https://www.youtube.com/watch?v=aAb7hSCtvGw
  140. @theburningmonk your abstractions should afford right behaviour, whilst make it impossible to do the wrong thing
  141. @theburningmonk “Make illegal states unrepresentable” - Yaron Minsky
  142. @theburningmonk discriminated unions
  143. @theburningmonk type PaymentMethod = | Cash | Cheque of ChequeNumber | Card of CardType * CardNumber finite, closed set of valid states ONLY
  144. closed hierarchy
  145. no Nulls
  146. @theburningmonk match paymentMethod with | Cash -> … | Cheque chequeNum -> … | Card (cardType, cardNum) -> …
  147. @theburningmonk Recap
  148. @theburningmonk immutability
  149. @theburningmonk make illegal state unrepresentable
  150. Getters and Setters
  151. “When it’s not necessary to change, it’s necessary to not change.” - Lucius Cary
  152. “Now we have shortcuts to do the wrong thing. We used to have type lots to do the wrong thing, not anymore.” - Kevlin Henney
  153. @theburningmonk immutability by default
  154. @theburningmonk type Person = { Name : string Age : int }
  155. @theburningmonk type Person = { mutable Name : string mutable Age : int }
  156. @theburningmonk immutability
  157. Uncohesive Tests
  158. @theburningmonk MethodA MethodB When_…Then_… () When_…Then_… () When_…Then_… () When_…Then_… () When_…Then_… () When_…Then_… ()
  159. @theburningmonk MethodA MethodB MethodC FeatureA FeatureB
  160. @theburningmonk complexities & potential bugs in the way methods work together
  161. @theburningmonk …especially when states are concerned
  162. @theburningmonk Test Driven Development
  163. “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
  164. @theburningmonk
  165. @theburningmonk how many tests?
  166. @theburningmonk every test has a cost
  167. @theburningmonk did we cover all the edge cases?
  168. @theburningmonk Property-Based Testing (with FsCheck)
  169. @theburningmonk List.rev reverse + reverse = original length of list is invariant append + reverse = reverse + prepend
  170. @theburningmonk List.rev property : reverse + reverse = original let ``reverse + reverse = original`` rev aList = aList |> rev |> rev = aList Check.Quick (``reverse + reverse = original`` List.rev) // Ok, passed 100 tests.
  171. @theburningmonk List.rev property : 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.
  172. @theburningmonk List.rev property : 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.
  173. @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]" [“HnOq6"; null; false; false; '#'] 6: true [“"] … 11: <null> ['014'; '0'; “nRH”; "<#oe"; true; false; ‘O'] …
  174. @theburningmonk shrinking
  175. @theburningmonk Check.Quick (``append + reverse = reverse + prepend`` id) // Falsifiable, after 2 tests (4 shrinks) (StdGen (1855582125,296080469)): Original: ‘013' ["}k"; ""; “"] Shrunk: true [false]
  176. @theburningmonk let computers do the grunt work
  177. source : http://bit.ly/1kEpEso
  178. @theburningmonk Types vs Tests
  179. @theburningmonk all bugs
  180. @theburningmonk unknown known
  181. @theburningmonk tests types
  182. @theburningmonk tests types
  183. @theburningmonk unit-testing distr. systems system-testing
  184. @theburningmonk Jepsenproperty-based unit-testing system-testing distr. systems
  185. @theburningmonk Jepsenproperty-based unit-testing types as proof TLA+ distr. systems system-testing
  186. Noisy Code Visual Dishonesty Lego Naming Underabstraction Unencapsulated State Getters and Setters Uncohesive Tests
  187. “Practice does not make perfect. Only perfect practice makes perfect.” - Vince Lombardi
  188. “Perfection is not attainable. But if we chase perfection, we can catch excellence.” - Vince Lombardi
  189. “Programming languages have a devious influence: they shape our thinking habits.” - Edsger W. Dijkstra
  190. “One of the most disastrous thing we can learn is the first programming language, even if it's a good programming language.” - Alan Kay
  191. “I’m not a great programmer; I’m just a good programmer with great habits.” - Kent Beck
  192. @theburningmonk what about ineffective coding habits SOME F#/FP programmers DO have?
  193. @theburningmonk
  194. @theburningmonk people are too puritanical about purity
  195. …premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3% - Donald Knuth
  196. @theburningmonk F# Map vs .Net array vs Dictionary
  197. @theburningmonk
  198. @theburningmonk Explicit is better than implicit. - the Zen of Python
  199. @theburningmonk Simple is better than Complex. Complex is better than Complicated. - the Zen of Python
  200. @theburningmonk Special cases aren't special enough to break the rules. - the Zen of Python
  201. @theburningmonk Special cases aren't special enough to break the rules. Although practicality beats purity. - the Zen of Python
  202. @theburningmonk If the implementation is hard to explain, it's a bad idea. - the Zen of Python
  203. @theburningmonk @theburningmonk theburningmonk.com github.com/theburningmonk
  204. @theburningmonk is hiring :-) http://tech.just-eat.com/jobs
  • ZourSouth

    Nov. 11, 2021
  • amamaj

    Mar. 10, 2021
  • ThomasThomas113

    Feb. 26, 2021
  • eddy_ni

    Oct. 31, 2020
  • helloworldgr

    Jun. 24, 2020
  • davye

    Apr. 29, 2020
  • jjapan1

    Mar. 2, 2020
  • omaruriel

    Jan. 27, 2020
  • vinipolicena

    Jan. 1, 2020
  • IsrelitosantosTavare

    Dec. 6, 2019
  • FernandoMendesFernandez

    Nov. 13, 2019
  • ShrikantDevanpalle

    Oct. 1, 2019
  • carlospavanetti

    Sep. 29, 2019
  • ashutoshmalviya5

    Sep. 18, 2019
  • gopalKrishnaDannaram

    May. 24, 2019
  • sidjidev143

    Apr. 16, 2019
  • AbdLaliBenakka

    Feb. 25, 2019
  • JennyMazaLicMassaget

    Jan. 25, 2019
  • waelsamir

    Sep. 29, 2018
  • Chethankodenkiri

    Aug. 19, 2018

At BuildStuff'14, Kevlin Henney presented an excellent talk titled "Seven ineffective coding habits of many programmers". As an attendee that day and someone who has exhibited many of these habits over the years, I came to realize that using F# has cured me of many of these ineffective habits! In this talk I'll share my thoughts on how the use of F# and functional programming techniques can help form and nurture good habits and give you the perfect practice you need to make perfect.

Views

Total views

698,874

On Slideshare

0

From embeds

0

Number of embeds

7,336

Actions

Downloads

240

Shares

0

Comments

0

Likes

181

×