affordances in programming languages

67
3/20/2014 Affordances http://localhost:9090/onepage 1/67 Affordances in Programming Languages Randy Coulman Principal Software Engineer http://randycoulman.com @randycoulman randycoulman

Upload: randy-coulman

Post on 26-Dec-2014

855 views

Category:

Technology


1 download

DESCRIPTION

From Mountain West Ruby Conference 2014. A good design communicates the intended use of an object. In the physical world, this communication is accomplished by “affordances”, as discussed by Donald Norman in “The Psychology of Everyday Things”. Programming languages also have affordances, and they influence the kinds of solutions we develop. The more languages we know, the more we “expand our design space” so that we can come up with better solutions to the problems we face every day.

TRANSCRIPT

Page 1: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 1/67

Affordances inProgramming Languages

Randy CoulmanPrincipal Software Engineer

http://randycoulman.com

 @randycoulman

 randycoulman

Page 2: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 2/67

Satu Kyröläinen ­ http://www.satukyrolainen.com/affordances/

Page 3: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 3/67

Satu Kyröläinen ­ http://www.satukyrolainen.com/affordances/

Page 4: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 4/67

Affordance

A quality of an object or environment that allows someone toperform an action.

Page 5: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 5/67

Nicolas Nova ­ http://www.flickr.com/photos/nnova/2252222949/

Page 6: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 6/67

William Lindeke ­ http://tcsidewalks.blogspot.com/2009/06/signs­of­times­14.html

Page 7: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 7/67

Yoni Alter ­ http://www.yoniishappy.com/Tube­escalators

Page 8: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 8/67

Affordances and Software

Page 9: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 9/67

Amir Rajan (@amirrajan)

Coding Out Loud ­ REST APIs series

http://vimeo.com/channels/659338

Page 10: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 10/67

ExamplePoints

Smalltalk ­> Ruby

Page 11: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 11/67

class Point def initialize(x, y) @x = x @y = y endend

Point.new(3, 4)

Page 12: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 12/67

http://images.cryhavok.org/d/25562­2/Polar+and+Cartesian+Bears.jpg

Page 13: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 13/67

θ

r sinθ

r cosθ

r

x

y

http://upload.wikimedia.org/wikipedia/commons/7/78/Polar_to_cartesian.svg

Page 14: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 14/67

class Point def initialize(x, y) @x = x @y = y endend

Point.new(3, 4)

Page 15: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 15/67

Point class>>x: anX y: aY ̂self new initializeX: anX y: aY

Point>>initializeX: anX y: aY x := anX. y := aY

Point x: 3 y: 4

Page 16: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 16/67

Point class>> r: radius theta: angleInRadians ̂self x: radius * angleInRadians cos y: radius * angleInRadians sin

Point r: 5 theta: 0.927295

Page 17: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 17/67

Affordance

Named Constructors

Page 18: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 18/67

class Point def self.xy(x, y) new(x, y) end

def self.polar(r, theta) xy(r * Math.cos(theta), r * Math.sin(theta)) end

private_class_method :new

# ... rest same as beforeend

Point.xy(3, 4)Point.polar(5, 0.927295)

Page 19: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 19/67

ExampleFind/DetectSmalltalk ­> Ruby

Page 20: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 20/67

#(2 4 6 8) detect: [:each | each odd]

"Unhandled exception: Element Not Found"

Page 21: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 21/67

[2, 4, 6, 8].find { |n| n.odd? }

# => nil

Page 22: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 22/67

#(2 4 6 8) detect: [:each | each odd] ifNone: [#none]

"#none"

Page 23: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 23/67

Affordance

Multiple Blocks

Page 24: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 24/67

[2, 4, 6, 8].find(-> {:none}) { |n| n.odd?} # => :none

Page 25: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 25/67

Linguistic Relativitya.k.a. The Sapir­Whorf Hypothesis

"[T]he structure of a language affects the ways in which itsrespective speakers conceptualize their world ... or otherwiseinfluences their cognitive processes."

­­ http://en.wikipedia.org/wiki/Linguistic_relativity

Page 26: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 26/67

When Code CriesCory Foy at SCNA 2012

http://vimeo.com/53986875

What does a language allow you to say?

What does a language force you to say?

Page 27: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 27/67

The Power and Philsophy of RubyMatz at OSCON 2003

http://www.rubyist.net/~matz/slides/oscon2003/mgp00001.html

"Languages are not only tools to communicate, but also toolsto think."

Page 28: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 28/67

ExampleCleaning Up After Yourself

C++ ­> Ruby

Page 29: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 29/67

if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail;if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != goto fail; goto fail;if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail;

//...

fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err;

Page 30: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 30/67

#include "support.h"#include <iostream>

void foo(){ Resource* resource = acquireResource(); bar(resource);

if (baz(resource) != 42) return;

std::cout << "Completed successfully!" << std::endl;

releaseResource(resource);}

Page 31: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 31/67

$ ./brokenAcquiring resourceCaught exception: oops!

Page 32: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 32/67

#include "support.h"#include <iostream>

void foo(){ Resource* resource = acquireResource();

try { bar(resource);

if (baz(resource) == 42) { std::cout << "Completed successfully!" << std::endl; } } catch(std::exception& e) { releaseResource(resource); throw; }

releaseResource(resource);}

Page 33: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 33/67

$ ./wordyAcquiring resourceReleasing resourceCaught exception: oops!

Page 34: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 34/67

#include "support.h"#include <iostream>

void foo(){ Resource* resource = acquireResource();

try { bar(resource);

if (baz(resource) == 42) { std::cout << "Completed successfully!" << std::endl; } } catch(std::exception& e) { releaseResource(resource); throw; }

releaseResource(resource);}

Page 35: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 35/67

Page 36: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 36/67

RAIIResource Acquisition Is Initialization

Acquire resources in the constructor

Release them in the destructor

Page 37: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 37/67

#include "SafeResource.h"#include "support.h"

SafeResource::SafeResource() : resource(acquireResource()){}

SafeResource::~SafeResource(){ releaseResource(resource);}

Resource* SafeResource::get(){ return resource;}

Page 38: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 38/67

#include "SafeResource.h"#include "support.h"#include <iostream>

void foo(){ SafeResource resource; bar(resource.get());

if (baz(resource.get()) != 42) return

std::cout << "Completed successfully!" << std::endl;}

Page 39: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 39/67

$ ./raiiAcquiring resourceReleasing resourceCaught exception: oops!

Page 40: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 40/67

Affordance

Deterministic Destructors

Page 41: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 41/67

Ruby doesn't have deterministic destructors.So what can we do instead?

Page 42: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 42/67

Blocks!

Page 43: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 43/67

class SafeResource def self.acquire resource = self.new yield resource ensure resource.release end

def initialize puts "Acquiring resource" @resource = Object.new end

def release puts "Releasing resource" @resource = nil end

Page 44: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 44/67

require_relative "support"require_relative "safe_resource"

def foo SafeResource.acquire do |resource| bar(resource)

return unless baz(resource) == 42

puts "Completed successfully!" endend

Page 45: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 45/67

$ ruby driver.rbAcquiring resourceReleasing resourceCaught exception: oops!

Page 46: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 46/67

ExampleImageReaderSmalltalk ­> Ruby

Page 47: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 47/67

ImageReader class>>fromFile: aFilename | readerClass imageStream reader |

imageStream := aFilename readStream binary. [readerClass := self readerClassFor: imageStream. readerClass ifNil: [̂self error: 'Unknown image type: ', aFilename asString]. reader := readerClass on: imageStream] ensure: [imageStream close]. ̂reader

Page 48: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 48/67

ImageReader class>>readerClassFor: imageStream ̂self subclasses detect: [:eachClass | imageStream reset. [eachClass canRead: imageStream] ensure: [imageStream reset]] ifNone: [nil]

Page 49: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 49/67

Affordance

Subclass Iteration

Page 50: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 50/67

class ImageReader

def self.read(filename) File.open(filename, "rb") do |io| reader_class = find_reader_class(io) raise "Unknown image type: #{filename}" unless reader_class reader_class.new(io) end end

#...end

Page 51: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 51/67

class ImageReader #...

def self.find_reader_class(io) subclasses.find { |reader| begin io.rewind reader.can_read?(io) ensure io.rewind end } end

#...end

Page 52: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 52/67

class ImageReader #...

def self.inherited(subclass) subclasses << subclass end

def self.subclasses @subclasses ||= [] end

#...end

Page 53: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 53/67

class BMPImageReader < ImageReader def self.can_read?(io) io.read(2) == "BM" end

def read_image puts "Reading BMP" endend

Page 54: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 54/67

class JPGImageReader < ImageReader def self.can_read?(io) io.read(2) == "\xFF\xD8".b end

def read_image puts "Reading JPG" endend

Page 55: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 55/67

class PNGImageReader < ImageReader def self.can_read?(io) io.read(8) == "\x89PNG\r\n\x1A\n".b end

def read_image puts "Reading PNG" endend

Page 56: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 56/67

require_relative "image_readers"

%w{bmp jpg png}.each do |ext| ImageReader.read("example.#{ext}")end

Page 57: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 57/67

$ ruby subclasses.rbReading BMPReading JPGReading PNG

Page 58: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 58/67

Takeaways

Page 59: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 59/67

Languages afford certain designsand inhibit others

Page 60: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 60/67

Languages influence thought

Page 61: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 61/67

Learning new languages willincrease your "solution space"

Page 62: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 62/67

Don't go too far

Page 63: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 63/67

Want More?http://randycoulman.com/blog/categories/affordances/

Page 64: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 64/67

AcknowledgementsKey Technology (http://www.key.net/)

Rogue.rb (@roguerb)

Jen Myers (@antiheroine)

Page 65: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 65/67

ReferencesThe Design of Every Day Things ­ Donald Norman

Coding Out Loud ­ Amir Rajan

Linguistic Relativity ­ Wikipedia article

When Code Cries ­ Cory Foy at SCNA 2012

The Power and Philosophy of Ruby ­ Matz at OSCON 2003

Page 66: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 66/67

Questions?

Page 67: Affordances in Programming Languages

3/20/2014 Affordances

http://localhost:9090/onepage 67/67

Randy Coulmanhttp://speakerrate.com/randycoulman

http://www.slideshare.net/randycoulmanhttp://randycoulman.com

 @randycoulman

 randycoulman