Friday, 9 May 14 Welcome to your New Project Friday, 9 May 14 - - PowerPoint PPT Presentation

friday 9 may 14 welcome to your new project
SMART_READER_LITE
LIVE PREVIEW

Friday, 9 May 14 Welcome to your New Project Friday, 9 May 14 - - PowerPoint PPT Presentation

Friday, 9 May 14 Welcome to your New Project Friday, 9 May 14 Friday, 9 May 14 Friday, 9 May 14 Things are starting to smell Friday, 9 May 14 Code Smells Symptoms in the source code that indicate there may be trouble ahead: Bugs Reduced


slide-1
SLIDE 1

Friday, 9 May 14

slide-2
SLIDE 2

Welcome to your New Project

Friday, 9 May 14

slide-3
SLIDE 3

Friday, 9 May 14

slide-4
SLIDE 4

Friday, 9 May 14

slide-5
SLIDE 5

Things are starting to smell

Friday, 9 May 14

slide-6
SLIDE 6

Code Smells

Symptoms in the source code that indicate there may be trouble ahead: Bugs Reduced development speed Readability/maintainability problems Heuristics, not hard and fast rules

Friday, 9 May 14

slide-7
SLIDE 7

Example: Long parameter Lists

¡

(defn ¡make-­‑cheese ¡ ¡ ¡[name ¡ ¡ ¡region ¡ ¡ ¡country ¡ ¡ ¡aoc? ¡ ¡ ¡pdo? ¡ ¡ ¡doc? ¡ ¡ ¡milk-­‑origin ¡ ¡ ¡milk-­‑origin-­‑subspecies ¡ ¡ ¡pastuerized? ¡ ¡ ¡aging-­‑time ¡ ¡ ¡mould-­‑type])

Friday, 9 May 14

slide-8
SLIDE 8

Example: Long parameter Lists

¡

(defn ¡make-­‑cheese ¡ ¡ ¡[name ¡ ¡ ¡region ¡ ¡ ¡country ¡ ¡ ¡aoc? ¡ ¡ ¡pdo? ¡ ¡ ¡doc? ¡ ¡ ¡milk-­‑origin ¡ ¡ ¡milk-­‑origin-­‑subspecies ¡ ¡ ¡pastuerized? ¡ ¡ ¡aging-­‑time ¡ ¡ ¡mould-­‑type])

(make-­‑cheese ¡"Bleu ¡de ¡Gex" ¡ ¡"Jura" ¡ ¡"France" ¡true ¡ ¡false ¡ ¡false ¡ ¡:cows ¡ ¡"Montbéliard" ¡ ¡false ¡ ¡(weeks ¡3) ¡ ¡"Penicillium ¡glaucum") ¡ (make-­‑cheese ¡ ¡"Stilton" ¡ ¡["Derbyshire" ¡"Leicestershire" ¡ "Nottinghamshire"] ¡ ¡"United ¡Kingdom" ¡ ¡false ¡ ¡true ¡ ¡false ¡ ¡:cows ¡ ¡"local" ¡ ¡true ¡ ¡(weeks ¡9) ¡ ¡"Penicillium ¡roqueforti")

Friday, 9 May 14

slide-9
SLIDE 9

What smells?

Hard to read Hard to change Error prone (easy to switch around literals)

Friday, 9 May 14

slide-10
SLIDE 10

What smells?

Hard to read Hard to change Error prone (easy to switch around literals)

Next steps

Obvious refactoring: extract parameter

  • bjects, alternative

functions make-­‑uk-­‑ cheese But... indicates underlying issues with how we have chosen to model our data - can we address that too?

Friday, 9 May 14

slide-11
SLIDE 11

“Standard” Code Smells

Martin Fowler + Kent Beck in “Refactoring...”: http:// www.amazon.co.uk/Refactoring- Improving-Design-Existing-Technology/ dp/0201485672 Define a standard set of smells focussed on OO and statically typed languages (Java)

Friday, 9 May 14

slide-12
SLIDE 12

Taxonomy

Mäntylä, M. V. and Lassenius, C. "Subjective Evaluation of Software Evolvability Using Code Smells: An Empirical Study". Journal of Empirical Software Engineering, vol. 11, no. 3, 2006, pp. 395-431.

BLOATERS Long Method Large Class Primitive Obsession Long Parameter List DataClumps OO ABUSERS Switch Statements Temporary Field Refused Bequest Alternative Classes with Different Interfaces CHANGE PREVENTERS Divergent Change Shotgun Surgery Parallel Inheritance Hierarchies DISPENSIBLES Lazy class Data class Duplicate Code Dead Code Speculativ e Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Friday, 9 May 14

slide-13
SLIDE 13

What do code smells look like in Clojure?

(Or: What do they smell like?)

Friday, 9 May 14

slide-14
SLIDE 14

... and why do we care?

Friday, 9 May 14

slide-15
SLIDE 15

My CV

2000s

C

Pascal C#

2010s

C++

Java JavaScript Ruby Clojure

Friday, 9 May 14

slide-16
SLIDE 16

My CV

2000s

C

Pascal C#

2010s

C++

Java JavaScript Ruby Clojure

IMPERATIVE

EXPRESSION ORIENTED

Friday, 9 May 14

slide-17
SLIDE 17

My CV

2000s

C

Pascal C#

2010s

C++

Java JavaScript Ruby Clojure

(Mainly) OO

FUNCTIONAL

Friday, 9 May 14

slide-18
SLIDE 18

Friday, 9 May 14

slide-19
SLIDE 19

Building on prior work

BLOATERS Long Method Large Class Primitive Obsession Long Parameter List DataClumps OO ABUSERS Switch Statements Temporary Field Refused Bequest Alternative Classes with Different Interfaces CHANGE PREVENTERS Divergent Change Shotgun Surgery Parallel Inheritance Hierarchies DISPENSIBLES Lazy class Data class Duplicate Code Dead Code Speculativ e Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Friday, 9 May 14

slide-20
SLIDE 20

OO-Specific Stuff

BLOATERS Long Method Large Class Primitive Obsession Long Parameter List DataClumps OO ABUSERS Switch Statements Temporary Field Refused Bequest Alternative Classes with Different Interfaces CHANGE PREVENTERS Divergent Change Shotgun Surgery Parallel Inheritance Hierarchies DISPENSIBLES Lazy class Data class Duplicate Code Dead Code Speculative Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Friday, 9 May 14

slide-21
SLIDE 21

A few edits...

BLOATERS

Long method function Large Class namespace

Primitive Obsession Long Parameter List DataClumps CHANGE PREVENTERS Divergent Change Shotgun Surgery DISPENSIBLES

Lazy Class function

Duplicate Code Dead Code Speculative Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Friday, 9 May 14

slide-22
SLIDE 22

Mäntylä, M. V. and Lassenius, C. "Subjective Evaluation of Software Evolvability Using Code Smells: An Empirical Study". Journal of Empirical Software Engineering, vol. 11, no. 3, 2006, pp. 395-431.

BLOATERS Long function Large namespace Long Parameter List DataClumps CHANGE PREVENTERS Divergent Change Shotgun Surgery DISPENSIBLES Lazy function Duplicate Code Dead Code Speculative Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Primitive Obsession

Primitive Obsession

“Primitive Obsession is using primitive data types to represent domain

  • ideas. For example, we use a String to represent a message, an Integer to

represent an amount of money, or a Struct/Dictionary/Hash to represent a specific object.” http://c2.com/cgi/wiki?PrimitiveObsession

... are collections in Clojure that primitive?

A few edits...

Friday, 9 May 14

slide-23
SLIDE 23

Clojure-specific Smells

DYS-FUNCTIONAL CODE

??? ??? ??? ???

Friday, 9 May 14

slide-24
SLIDE 24

Magic Keys

(clavis magica)

AKA: Data structure coupling Over-sharing structure / content of maps/records leading to implicit coupling

Friday, 9 May 14

slide-25
SLIDE 25

Example

{ ¡:name ¡"Stilton" ¡ ¡:milk ¡{:milk-­‑type ¡:cows ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡:origin-­‑subspecies ¡"local" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡:is-­‑pasteurized? ¡true} ¡ ¡:mould-­‑type ¡"Penicillium ¡roqueforti" ¡ ¡:region ¡ ¡ ¡["Derbyshire" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡"Leicestershire" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡"Nottinghamshire"] ¡ ¡:country ¡"United ¡Kingdom" ¡ ¡:aging-­‑time ¡nil}

Friday, 9 May 14

slide-26
SLIDE 26

Example

(defn ¡calculate-­‑olfactory-­‑offence ¡ ¡[{:keys ¡[milk ¡mould-­‑type ¡aging-­‑time ¡washing-­‑solution]}] ¡ ¡(let ¡[pasteurization-­‑factor ¡(if ¡(:is-­‑pasteurized? ¡milk) ¡0.5 ¡1)] ¡ ¡ ¡ ¡(* ¡aging-­‑time ¡ ¡ ¡ ¡ ¡ ¡ ¡(+ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(milk-­‑type-­‑>smell ¡(:milk-­‑type ¡milk)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡pasteurization-­‑factor ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(mould-­‑>smell ¡mould-­‑type) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(washing-­‑solution-­‑>smell ¡washing-­‑solution-­‑>smell))))) ¡ (defn ¡lactose-­‑levels ¡[{:keys ¡[milk ¡quantity]}] ¡ ¡(if ¡(:is-­‑pasteurized? ¡milk) ¡ ¡ ¡ ¡(calculate-­‑pasteurized-­‑lactose-­‑levels ¡quantity ¡(:milk-­‑type ¡milk)) ¡ ¡ ¡ ¡(calculate-­‑unpasteurized-­‑lactose-­‑levels ¡quantity ¡(:milk-­‑type ¡milk))))

Friday, 9 May 14

slide-27
SLIDE 27

Example

(defn ¡calculate-­‑olfactory-­‑offence ¡ ¡[{:keys ¡[milk ¡mould-­‑type ¡aging-­‑time ¡washing-­‑solution]}] ¡ ¡(let ¡[pasteurization-­‑factor ¡(if ¡(:is-­‑pasteurized? ¡milk) ¡0.5 ¡1)] ¡ ¡ ¡ ¡(* ¡aging-­‑time ¡ ¡ ¡ ¡ ¡ ¡ ¡(+ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(milk-­‑type-­‑>smell ¡(:milk-­‑type ¡milk)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡pasteurization-­‑factor ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(mould-­‑>smell ¡mould-­‑type) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(washing-­‑solution-­‑>smell ¡washing-­‑solution-­‑>smell))))) ¡ (defn ¡lactose-­‑levels ¡[{:keys ¡[milk ¡quantity]}] ¡ ¡(if ¡(:is-­‑pastuerized? ¡milk) ¡ ¡ ¡ ¡(calculate-­‑pastuerized-­‑lactose-­‑levels ¡quantity ¡(:milk-­‑type ¡milk)) ¡ ¡ ¡ ¡(calculate-­‑unpasteurized-­‑lactose-­‑levels ¡quantity ¡(:milk-­‑type ¡milk)))) ¡

Friday, 9 May 14

slide-28
SLIDE 28

What smells?

Hard to figure out the cost of change of key names, data types etc. Unexpected errors if data is in the wrong shape in production ... too many fns know the intimate details about the structure. Easy mess to get into - tradeoff of modelling data as maps

Friday, 9 May 14

slide-29
SLIDE 29

What smells?

Hard to figure out the cost of change of key names, data types etc. Unexpected errors if data is in the wrong shape in production ... too many fns know the intimate details about the structure. Easy mess to get into - tradeoff of modelling data as maps

What to do

Keep data-aware fns together (defrecord?) Minimise how many fns know about structure For data that is coming from elsewhere, consider core.contracts or something like Schema to add appropriate checks

Friday, 9 May 14

slide-30
SLIDE 30

Better?

(defn ¡milk-­‑>smell ¡[{:keys ¡[milk-­‑type ¡is-­‑pasteurized?]}] ¡ ¡(+ ¡ ¡ ¡(if ¡is-­‑pasterurized? ¡0.5 ¡1) ¡ ¡ ¡(milk-­‑type-­‑>smell ¡milk-­‑type))) ¡ (defn ¡lactose-­‑levels ¡[{:keys ¡[milk-­‑origin ¡is-­‑pasteurized?]}] ¡ ¡(if ¡is-­‑pasteurized? ¡ ¡ ¡ ¡(calculate-­‑pasteurized-­‑lactose-­‑levels ¡milk-­‑origin) ¡ ¡ ¡ ¡(calculate-­‑unpasteurized-­‑lactose-­‑levels ¡milk-­‑origin)))

Getting there.

Friday, 9 May 14

slide-31
SLIDE 31

Parens Proliferation

(involvimus in aeternum)

AKA: Over-nesting Excessive nesting of expressions making things hard to read and understand

Friday, 9 May 14

slide-32
SLIDE 32

Example

(defn ¡make-­‑mozarella ¡[citric-­‑acid ¡rennet ¡milk] ¡ ¡(zipmap ¡[:curds ¡:whey] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(separate ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(stir-­‑for ¡(minutes ¡5) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(warm-­‑to ¡(farenheit ¡105) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(cut-­‑into-­‑squares ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(leave-­‑until-­‑turned-­‑into-­‑curds ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(minutes ¡5) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(combine ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(dissolve-­‑in-­‑water ¡rennet) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(warm-­‑to ¡(farenheit ¡90) ¡milk)))))))))

Friday, 9 May 14

slide-33
SLIDE 33

Example

(defn ¡make-­‑mozarella ¡[citric-­‑acid ¡rennet ¡milk] ¡ ¡(zipmap ¡[:curds ¡:whey] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(separate ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(stir-­‑for ¡(minutes ¡5) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(warm-­‑to ¡(farenheit ¡105) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(cut-­‑into-­‑squares ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(leave-­‑until-­‑turned-­‑into-­‑curds ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(minutes ¡5) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(combine ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(dissolve-­‑in-­‑water ¡rennet) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(warm-­‑to ¡(farenheit ¡90) ¡milk)))))))))

Friday, 9 May 14

slide-34
SLIDE 34

What smells?

Trying to do everything on

  • ne line

Easy to evaluate, hard to read, nightmare to debug Side-affect of being an expression-oriented language

Friday, 9 May 14

slide-35
SLIDE 35

What smells?

Trying to do everything on

  • ne line

Easy to evaluate, hard to read, nightmare to debug Side-affect of being an expression-oriented language

What to do

Keep a balance between terseness and readability: not everything needs to be on one line! Excessive )))))) is a good heuristic let, ¡-­‑>, ¡-­‑>> are your friends

Friday, 9 May 14

slide-36
SLIDE 36

Better?

(defn ¡make-­‑mozarella-­‑improved ¡[citric-­‑acid ¡rennet ¡milk] ¡ ¡(let ¡[ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rennet-­‑solution ¡(dissolve-­‑in-­‑water ¡rennet) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡warmed-­‑milk ¡(warm-­‑to ¡(farenheit ¡90) ¡milk)] ¡ ¡ ¡ ¡(-­‑>> ¡[rennet-­‑solution ¡warmed-­‑milk] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(combine) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(leave-­‑until-­‑turned-­‑into-­‑curds) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(cut-­‑into-­‑squares) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(warm-­‑to ¡(farenheit ¡105)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(stir-­‑for ¡(minutes ¡5)) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(separate) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡(zipmap ¡[:curds ¡:whey]))))

If recipes looked like this, I would be a better cheese maker

Friday, 9 May 14

slide-37
SLIDE 37

Lazi-itis

(codex dormientes)

Nested levels of lazy sequences leading to errors popping up in confusing places

Friday, 9 May 14

slide-38
SLIDE 38

Example

What happens if ‘load-cheese-by-id’ has a database connection problem?

(defn ¡cheese-­‑smell-­‑analyser ¡[cheeses-­‑to-­‑assess] ¡ ¡(-­‑>> ¡cheeses-­‑to-­‑assess ¡ ¡ ¡ ¡ ¡ ¡ ¡(map ¡parse-­‑cheese-­‑ids) ¡ ¡ ¡ ¡ ¡ ¡ ¡(map ¡load-­‑cheese-­‑by-­‑id) ¡ ¡ ¡ ¡ ¡ ¡ ¡(map ¡#(select-­‑keys ¡% ¡[:mould-­‑type ¡:aging-­‑time])) ¡ ¡ ¡ ¡ ¡ ¡ ¡(map ¡get-­‑odour-­‑level) ¡ ¡ ¡ ¡ ¡ ¡ ¡(reduce ¡#(merge-­‑with ¡max ¡%1 ¡%2) ¡{})))

Friday, 9 May 14

slide-39
SLIDE 39

Stack trace

java.lang.Exception: ¡Kablammo ¡at ¡cheese_factory.mozarella$load_cheese_by_id.invoke ¡(cheese.clj:66) ¡ ¡ ¡ ¡clojure.core$map$fn__4207.invoke ¡(core.clj:2485) ¡ ¡ ¡ ¡clojure.lang.LazySeq.sval ¡(LazySeq.java:42) ¡ ¡ ¡ ¡clojure.lang.LazySeq.seq ¡(LazySeq.java:60) ¡ ¡ ¡ ¡clojure.lang.RT.seq ¡(RT.java:484) ¡ ¡ ¡ ¡clojure.core$seq.invoke ¡(core.clj:133) ¡ ¡ ¡ ¡clojure.core$map$fn__4207.invoke ¡(core.clj:2479) ¡ ¡ ¡ ¡clojure.lang.LazySeq.sval ¡(LazySeq.java:42) ¡ ¡ ¡ ¡clojure.lang.LazySeq.seq ¡(LazySeq.java:60) ¡ ¡ ¡ ¡clojure.lang.RT.seq ¡(RT.java:484) ¡ ¡ ¡ ¡clojure.core$seq.invoke ¡(core.clj:133) ¡ ¡ ¡ ¡clojure.core$map$fn__4207.invoke ¡(core.clj:2479) ¡ ¡ ¡ ¡clojure.lang.LazySeq.sval ¡(LazySeq.java:42) ¡ ¡ ¡ ¡clojure.lang.LazySeq.seq ¡(LazySeq.java:60) ¡ ¡ ¡ ¡clojure.lang.RT.seq ¡(RT.java:484) ¡ ¡ ¡ ¡clojure.core$seq.invoke ¡(core.clj:133) ¡ ¡ ¡ ¡clojure.core.protocols$seq_reduce.invoke ¡(protocols.clj:30) ¡ ¡ ¡ ¡clojure.core.protocols/fn ¡(protocols.clj:54) ¡ ¡ ¡ ¡clojure.core.protocols$fn__5979$G__5974__5992.invoke ¡(protocols.clj:13) ¡ ¡ ¡ ¡clojure.core$reduce.invoke ¡(core.clj:6177) ¡ ¡ ¡ ¡cheese_factory.mozarella$cheese_smell_analyser.invoke ¡(NO_SOURCE_FILE:3) ¡ ¡ ¡ ¡cheese_factory.mozarella$eval1517.invoke ¡(NO_SOURCE_FILE:1) ¡ ¡ ¡ ¡clojure.lang.Compiler.eval ¡(Compiler.java:6619) ¡ ¡ ¡ ¡clojure.lang.Compiler.eval ¡(Compiler.java:6582) ¡ ¡ ¡ ¡clojure.core$eval.invoke ¡(core.clj:2852) ¡ ¡ ¡ ¡clojure.main$repl$read_eval_print__6588$fn__6591.invoke ¡(main.clj:259) ¡ ¡ ¡ ¡clojure.main$repl$read_eval_print__6588.invoke ¡(main.clj:259) ¡ ¡ ¡...

Friday, 9 May 14

slide-40
SLIDE 40

What smells?

Many discrete steps with final step that executes the sequence Hard to isolate failures (which cheese didn’t load?)

Friday, 9 May 14

slide-41
SLIDE 41

What smells?

Many discrete steps with final step that executes the sequence Hard to isolate failures (which cheese didn’t load?)

What to do

Friday, 9 May 14

slide-42
SLIDE 42

What smells?

Many discrete steps with final step that executes the sequence Hard to isolate failures (which cheese didn’t load?)

What to do

Consider pulling things into coarser-grained steps to avoid long pipelines Add in failure mode support for external system access - not just exceptions! Realise lazy sequences in a consistent way - module boundaries?

Friday, 9 May 14

slide-43
SLIDE 43

Better?

(defn ¡cheese-­‑smell-­‑analyser-­‑2 ¡[cheeses-­‑to-­‑assess] ¡ ¡(-­‑>> ¡cheeses-­‑to-­‑assess ¡ ¡ ¡ ¡ ¡ ¡ ¡(load-­‑cheeses) ¡ ¡ ¡ ¡ ¡ ¡ ¡(map ¡get-­‑odour-­‑level) ¡ ¡ ¡ ¡ ¡ ¡ ¡(reduce ¡calculate-­‑stats)))

TODO: Better error handling...

Friday, 9 May 14

slide-44
SLIDE 44

Clojure Code Smells

BLOATERS Long function Large namespace Long Parameter List DataClumps CHANGE PREVENTERS Divergent Change Shotgun Surgery DISPENSIBLES Lazy function Duplicate Code Dead Code Speculative Generality COUPLERS Feature Envy Inappropriate Intimacy Message Chains Middle Man Primitive Obsession

DYS-FUNCTIONAL CODE

Magic Keys Parenthesen Proliferation Lazy-itis Friday, 9 May 14

slide-45
SLIDE 45

Other suggestions

Macromania Indirection by partiality Locally scoped atoms (more?)

Friday, 9 May 14

slide-46
SLIDE 46

Do we need code smells?

Friday, 9 May 14

slide-47
SLIDE 47

Do we need code smells?

Friday, 9 May 14

slide-48
SLIDE 48

Do we need code smells?

Friday, 9 May 14

slide-49
SLIDE 49

The common factor Software developer

(Codex scriptor familiaris)

Friday, 9 May 14

slide-50
SLIDE 50

Are smells just

  • verdoing it?

Data as maps => magic keys Lazy sequences => lazyitis expression-oriented => parens proliferation macros => macromania partial function application => indirection by partiality

Friday, 9 May 14

slide-51
SLIDE 51

Probably...

We should be thinking more and writing less and evaluating the tradeoffs and applicability of our approaches Code smells can help us guide us in the right direction and learn from each other

Friday, 9 May 14

slide-52
SLIDE 52

FIN

Friday, 9 May 14

slide-53
SLIDE 53

Image credits

  • http://www.flickr.com/photos/photophilde/3514290419/
  • http://www.flickr.com/photos/marilynjane/341095494/
  • http://www.flickr.com/photos/jeremyrebelka/3242678416/
  • http://www.flickr.com/photos/huggleperson/7980839256/
  • http://www.flickr.com/photos/eighttrees/3225831955/
  • http://www.clker.com/clipart-key-vintage.html
  • https://twitter.com/otfrom

Friday, 9 May 14