Programming Language Technical debt and their influence in Thinking and Desgin

Post on 01-Dec-2014

268 views 1 download

description

Presentation used at Avanet meetup, Medellin 2014

Transcript of Programming Language Technical debt and their influence in Thinking and Desgin

agile software development & services

The Technical Debt of the Programming Languages

…and the influence in our thinking

and designs

Hernán WilkinsonMedellin 2014

The world “we live” in … ?

The world “we live” in … ?

The world “we live” in … ?

The world “we live” in … ?

Bret Victor - Thinking the unthinkable

Language implies Thinking

Language implies Thinking

Thinking implies Language

What we can not talk about…we can not think about

(or it is difficult...)

Do not Insist on English

Aimara: Pasado y Futuro (nayra) (qhipa)

Languages without a concept for the future — "It rain tomorrow," instead of "It will rain tomorrow" — correlate

strongly with high savings rates.

Now, a design problemLet’s think about this:

How do we call the whole thing?

Let’s say Traffic Light (Semáforo)

How do we call each part?

Let’s say Traffic Regulator(guess why not 'Traffic Controller'?)

How do we call each Traffic Regulator in the Traffic Light context?

aTrafficLight

northSouthRegulator

eastWestRegulator

aTrafficLight

rightRegulator

leftRegulator

aTrafficLight

regulator1

regulator2

Not easy way to name them…Relative vs. Fix Coordinate System

B. Lee Whorf(Linguistic Relativity)

What is the relationship with Programming Languages?

(K. Iverson: “Notation as a tool of thought”)

If a programming language does not allow me to “TALK” (write) about certain

things…

Then I can not THINK about certain

solutions

ABSTRACTION

How do we refer to that “thing that has four wheels and moves?”

and to “that thing that moves and has four wheels?”

and to “that one that moves because it has

four wheels?”

To avoid REPETITIONTo provide MEANING to that

REPETITION

If we have repetition we are lacking and abstraction… (an object in OO)

Meta Note: I repeated the picture… I’m lacking an abstraction or a better image!

Let’s seeList<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add (customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

What is the problem?

We have repeated code!List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add (customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

“Repeated code” does not mean “repeated text”.

It means “repeated patterns of collaboration”

What is the problem?

We are lacking an ABSTRACTION!

Repeated code means we are forgetting an object!

How do we remove it?

Technique:1. Copy the repeated code to some

“place”2. Parameterize what changes3. NAME IT!!!4. Use it :-)

Copy the repeated code to some placeList<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add(customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

class Collection<T> {

public Collection<T> <<NAME>> {

List<T> selected = new ArrayList<T> ();

for (T anObject: this )

if ( )

selected.add (anObject);

return selected: }

Parameterize what changes

List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add (customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

How do we do it?

We need an abstraction to represent “code”

We need a BLOCK or a CLOSURE…… an object that represents “code”

Parameterize what changes

class Collection<T> {public Collection<T> <<NAME>> (Closure aClosure) {

List<T> selected = new ArrayList<T> ();

for (T anObject: this)

if (aClosure.value(anObject) )

selected.add (anObject);

return selected:}

List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add(customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

NAME IT!!

class Collection<T> {public Collection<T> select (Closure aClosure) {

List<T> selected = new ArrayList<T> ();

for (T anObject: this)

if (aClosure.value(anObject) )

selected.add (anObject);

return selected:}

The most difficult part because it means that we understood the repeated code

meaning

List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add(customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

selectedCustomers.add (customer);

return selectedCustomers;

List<Account> selectedAccounts = new ArrayList<Account> ();

for (Account account: accounts)

if (account.isOverdraw())

selectedAccounts.add(account);

return selectedAccount;

cutomers.select( customer => customer.nameStartsWith(“H”) )

accounts.select( account => account.isOverdraw() )

customers.select( new SelectClosure<Customer> () {

public boolean value (Customer aCustomer) {

return aCustomer.nameStartsWith(“H”); }});

cutomers.select( customer => customber.nameStartsWith(“H”) )

Why not an Anonymous Class?1. Sintax:

Which one reads better?

2. Binding problems…

What did we gain?1. Few words Simplicity, Easier to

understand, read, remember, etc. Less bugs!

2. We created a new “abstraction”: select

3. … and we remove duplicated code!!

Now… let’s do some reflection

1. Why didn’t we see the “duplicated code”?

2. Why didn’t we came with a solution?

Why didn’t we see the “duplicated code”

1. Because we are use to that code (is the programming language the problem or us?)

2. Because there is no “concept” to remove it

Why didn’t we see the “duplicated code”

1. Because we are use to that code (is the programming language the problem or us?)

2. Because there is no “concept” to remove it

Why didn’t we came with a solution?1. Because the programming language

does not provide us with a “concept” to think about a solution!

DOES NOT REALLY?

cutomers reject: [ :aCustomer | aCustomer nameStartsWith: ‘H’ ] (Smalltalk)

customers.reject { | aCustomer | aCustomer.nameStartsWith(“H”) } (Ruby)

customers.Where( aCustomer => !aCustomer.nameStarsWith(“H”)) (C#)

rejectList<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (!customer.nameStarsWith(“H”))

selectedCustomers.add (customer);

return selectedCustomers;

List<Customer> selectedCustomers = new ArrayList<Customer> ();

for (Customer customer: customers)

if (customer.nameStarsWith(“H”))

return customer;

throw ….

customers detect: [ :aCustomer | aCustomer nameStartsWith: ‘H’ ](Smalltalk)

customers.detect { | aCustomer | aCustomer.nameStartsWith(“H”) } (Ruby)

customers.First ( aCustomer => aCustomer.nameStarstWith(“H”)) (C#)

detect

customers collect: [ :aCustomer | aCustomer name ] (Smalltalk)

customers.collect { | aCustomer | aCustomer.name () } (Ruby)

customers.Select( aCustomer => aCustomer.name() ) (C#)

collectList<String> customerNames = new ArrayList<String> ();

for (Customer customer: customers)

customerNames.add (customer.name());

return customerNames;

self

should: [ do something ]

raise: Exception

withExceptionDo: [ :e | self assert: …. ] (Smallalk)

TDD: Test for exceptionsTry {

… do something

fail()

} catch (Exception e) {

assertTrue (…. ) }

…and much much more….

Imagine how your designs would be if

you could use closures

You can create your own control flow “sintax”

Further reading: LAMBDA The Ultimate…

Meta-Conclusion

Object = ¿Data + Code?

Meta-Conclusion

Object = ¿Data + Code?

If you think so, you don´t understand OO yet

Mete-Conclusion

Data is an Object

Code is an Object

An Object is a “superior” concept that unifies data and

code

Hamming / Closure

If there are certain objects that can not be created in some languages …

… and given the solutions provided by some programming languages…

The statement: “There are design solutions that are unthinkable in some

programming languages”

¿Does it surprise you?

What is the problem?

No If!

If Implementation

“if” as a reserved word– What do we gain?– What do we loose?

“if” as a message– What do we gain?– What do we loose?

Boole’s Algebra

“if” as a message

Now… let’s do some reflection

1. Why didn’t we see the “polymorphic message”?

2. Why didn’t we came with a right solution?

Why didn’t we see the “polymorphic message”

Because 'if' as a reserved word does not make us think in polymorphism

How do we model 'age'?

How do we model 'Weight'?

How do we model 'money'?How do we model 'length'?How do we model 'speed'?

We need algebraic expressions

Let's see an example

Now… let’s do some reflection

1. Why don't we use algebraic expressions?

2. How does affect our design not to use them?

Because 'common programming languages' only provide arithmetic models

Because we don't realize that a language is the beginning not the end.

A programming language is its creator's state of knowledge

How does impact our design a language without extensible

classes?

ArrayHelper?? xxxManager??

How does impact our design a language where we can not see how it is implemented?

How can we add specific behavior to an object?

Let's see an example

Now… let’s do some reflection

1. What are the solutions we lack due to limited meta programming?

2. What do we loose if we do not have a meta-circular language?

How do we learn a new word?

Do we:1. Stop our brain2. “edit" a new definition in our

dictionary3. “Compile” the new definition4. Restart our brain?

NO!!

Why do we have to do it with our programs?

Can our programs “change while running”?

Can our programs “learn” as we learn?

Yes, they can!... If they areMETACIRCULAR

Apply

Eval

Let’s see a problem:Can you make a proxy “learn” about its

proxee as it is used?

If we don’t have meta-circular languages, then we can not think

about solutions where meta-programming would fit!

Let’s think again…

Are these concepts new?

Lisp

John McCarthy

Alan Kay

“We must know our historyif we don’t want to reinvent… not only the tire, but a a flat tire”

Even More! Static vs. Dynamic typing

languages?Design?TDD?

Frameworks?Relational Databases?Web applications?

Fuente: http://c2.com/cgi/wiki?WardExplainsDebtMetaphor

Technical Deb Metaphor…

Why not having closures generate debt?

Repeated code Lack of abstractions Difficult and costly to maintain

Why not having meta-programming generate debt?

Some problems are more difficult to solve More code!

Programs can not reason about programs or themselves

We always need a programmer to do something a program could do

Conclusions Do not accept languages without

Closures Do not accept languages without

good meta-programming Create your own extensions! Liberate yourself from the

programming language

Conclusions Learn other programming

languages Lisp/Scheme Smalltalk Forth and more...

Learn our history

We teach this and other important design aspects in our courses

• OO Design I & OO Design II• TDD & Advanced TDD

Check them out at:http://www.10pines.com/

Questions?

agile software development & services

Muchas gracias!

info@10pines.comwww.10Pines.com

twitter: @10Pines

Argentina

Tel.: +54 (11) 6091-3125Alem 693, 5B(1001) Buenos Aires