Date post: | 01-Dec-2014 |
Category: |
Software |
Upload: | hernan-wilkinson |
View: | 268 times |
Download: | 1 times |
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!
twitter: @10Pines
Argentina
Tel.: +54 (11) 6091-3125Alem 693, 5B(1001) Buenos Aires