+ All Categories
Home > Technology > Functional OOP, Clojure style

Functional OOP, Clojure style

Date post: 17-Nov-2014
Category:
Upload: yoavrubin
View: 2,183 times
Download: 0 times
Share this document with a friend
Description:
The presentation for the talk given at the reversim summit
Popular Tags:
100
Transcript
Page 1: Functional OOP, Clojure style
Page 2: Functional OOP, Clojure style

Functional OOP,Clojure Style

Yoav Rubin

Page 3: Functional OOP, Clojure style

About me• Software engineer at IBM Research - Haifa

– Development of development environments– Large scale products

to small scale research projects

• Lecture the course “Functional programming on the JVM” in Haifa University

{:name Yoav Rubin,:email [email protected],:blog http://yoavrubin.blogspot.com,:twitter @yoavrubin}

Page 4: Functional OOP, Clojure style

First thing first

Page 5: Functional OOP, Clojure style

Alan Kay

Page 6: Functional OOP, Clojure style

Alan Kay Edsger W. Dijkstra

Page 7: Functional OOP, Clojure style

Alan Kay Edsger W. Dijkstra

Page 8: Functional OOP, Clojure style

“Perspective is worth 80 IQ points”

Alan Kay

Page 9: Functional OOP, Clojure style

• OOP

• Clojure

Agenda

in

Page 10: Functional OOP, Clojure style

What’s in a software

• Data types that describe the elements of the domain (nouns)

• State changing operations (verbs)

Page 11: Functional OOP, Clojure style

Type \ functionalityf1f2f3f4

T1XX

T2X

T3X

T4XXXX

The software matrix

Page 12: Functional OOP, Clojure style

Type \ functionalityf1f2f3f4

T1XX

T2X

T3X

T4 XXXX

The software matrix

Data types, nouns

Page 13: Functional OOP, Clojure style

Type \ functionalityf1f2f3f4

T1XX

T2X

T3X

T4 XXXX

The software matrixAPI, verbs, interfaces

Page 14: Functional OOP, Clojure style

Type \ functionalityf1f2f3f4

T1XX

T2X

T3X

T4XXXX

The software matrix

implementations of operationx by Typey

Page 15: Functional OOP, Clojure style

Data directed programming

The expression problem

Philip Wadler

SICP

Deciding which function to use based on given data

How to add rows and columns to the matrix without recompiling while preserving static typing

Page 16: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Page 17: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Abstraction

Page 18: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Page 19: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Information hiding

Page 20: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Page 21: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Polymorphism

Page 22: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z

Page 23: Functional OOP, Clojure style

Let’s talk OOP

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in class

Z means that X is-a Z Inheritance

Page 24: Functional OOP, Clojure style

Type \ functionality

f1f2f3f4

T1XX

T2X

T3X

T4 XXX

Inheritance

Page 25: Functional OOP, Clojure style

Type \ functionality

f1f2f3f4

T1XX

T2X

T3X

T4 XXX

Inheritance

T4 can say that it is a T3

Page 26: Functional OOP, Clojure style

Type \ functionality

f1f2f3f4

T1XX

T2X

T3X

T4 XXX

Inheritance

T4 can say that it is a T3

and its implementation of f3 is found at T3

X

Page 27: Functional OOP, Clojure style

OOP on the matrix

• The rows are the classes– The domain abstractions we define and use– Which can hide within them their internal state

• The column headers are interfaces– Which allow polymorphic usage

• Marked cell in row X and column Y signifies that class X implements interface Y– Saying that the implementation itself resides in Class

Z means that X is-a Z

Page 28: Functional OOP, Clojure style

How is it all related to Clojure?

Page 29: Functional OOP, Clojure style

What is Clojure

Page 30: Functional OOP, Clojure style

What is Clojure

• A Lisp• A functional language• Dynamically typed• Emphasis on immutability• Treats concurrency as an elementary part of life

– Not as a burden• Compiles to bytecode

– Of the JVM / CLR / JS (as the web’s bytecode) • Excellent “great ideas to WTF” ratio

Page 31: Functional OOP, Clojure style

General structure

• A Clojure project is built of namespaces

• In each namespace there are functions and data elements

• Functions can be either public or private– Either visible or not visible outside of the

namespace

Page 32: Functional OOP, Clojure style

General structure

• A Clojure project is built of namespaces

• In each namespace there are functions and data elements

• Functions can be either public or private– Either visible or not visible outside of the

namespace Functional Information hiding

Page 33: Functional OOP, Clojure style

How to define rows in Clojure?

Page 34: Functional OOP, Clojure style

Creating new types

• Metaobjects – a mechanism that allows description and creation of new datatypes

• We can create our own metaobjects– E.g., a map that one of its key is “type”

• In Clojure there are two metaobjects– Type– Record

Page 35: Functional OOP, Clojure style

The Type metaobject

• Upon definition we need to provide:– Name – Member fields– APIs to implement and their implementation

• Override methods from Object, interfaces, protocols (soon)

• Cannot introduce new APIs to the matrix• Can be made mutable

Page 36: Functional OOP, Clojure style

The type metaobjectDefinition:

Instantiation:

Usage:

Page 37: Functional OOP, Clojure style

The type metaobjectDefinition:

Instantiation:

Usage:

Page 38: Functional OOP, Clojure style

The type metaobjectDefinition:

Instantiation:

Usage:

Page 39: Functional OOP, Clojure style

The type metaobjectDefinition:

Instantiation:

Usage:

Page 40: Functional OOP, Clojure style

Two main use cases

• You really know what you are doing

• You’re doing it wrong

Page 41: Functional OOP, Clojure style

The Record metaobject• Similar to the Type metaobject

• Provides a map like behavior

• No mutability

Page 42: Functional OOP, Clojure style

So far in the software matrix

• Added new rows– New types / records– No new APIs

• Associate with an existing column

Page 43: Functional OOP, Clojure style

So far in the software matrix

• Added new rows– New types / records– No new APIs

• Associate with an existing column

Functional Abstraction

Page 44: Functional OOP, Clojure style

So far in the software matrix

• Added new rows– New types / records– No new APIs

• Associate with an existing column

Functional Abstraction

Polymorphism

Page 45: Functional OOP, Clojure style

How to define columns in Clojure?

Page 46: Functional OOP, Clojure style

Adding new APIs

• New APIs for one type– just add a new function

• Problem: how to handle more types?

• Naïve solution: a simple dispatcher

Page 47: Functional OOP, Clojure style
Page 48: Functional OOP, Clojure style
Page 49: Functional OOP, Clojure style

Now there’s a new tree in town

Page 50: Functional OOP, Clojure style

What can a developer do?

• Re-write the existing tree-map function– Because editing legacy code is fun…

• Create another tree-map in another namespace and qualify its calls– Name collisions

• Create tree-map2– Complicating both developer’s and user’s code

Page 51: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

Page 52: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

New column header (API)

Page 53: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

New column header (API)

Two implementations

Page 54: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

New column header (API)

Two implementations

QuadTree

Page 55: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

New column header (API)

Two implementations

QuadTree ?

Page 56: Functional OOP, Clojure style

A deeper look

Type \ functionalityf1f2f3tree-map

GeneralTreeXXX

YetAnotherTypeX

BinaryTreeXX

New column header (API)

Two implementations

QuadTree ?

Tree-map did too much!!!

Page 57: Functional OOP, Clojure style

In the software matrix: Need to decomplect the creation of columns headers from cell marking

Or in software design language:We need to separate the definition of an API from its implementation

Page 58: Functional OOP, Clojure style

Creating abstract APIs

• No concrete implementation• Define a semantic unit

– A set of behaviors that compose an API

• In another place define the mapping between data types and the API– Marking of a cell in the matrix

Page 59: Functional OOP, Clojure style

Protocol

• A set of several function signatures– Just the signature, without implementation– Dispatch is done based on the run-time type

Page 60: Functional OOP, Clojure style

Protocol

• A set of several function signatures– Just the signature, without implementation– Dispatch is done based on the run-time type

The protocol name

Page 61: Functional OOP, Clojure style

Protocol

• A set of several function signatures– Just the signature, without implementation– Dispatch is done based on the run-time type

The protocol name

A function signature (there can be several of these)

Page 62: Functional OOP, Clojure style

Protocols and types

• The linking of a protocol to a type can be done not as part of the definition of the type

• This results in the possibility to extend existing, compiled types– Extend String– Extend even nil

Page 63: Functional OOP, Clojure style
Page 64: Functional OOP, Clojure style
Page 65: Functional OOP, Clojure style
Page 66: Functional OOP, Clojure style
Page 67: Functional OOP, Clojure style

Added to an existing type a new API

Without changing the type

Page 68: Functional OOP, Clojure style

Added to an existing type a new API

Without changing the type

Functional polymorphism

Page 69: Functional OOP, Clojure style

Still, there are limitations

Protocols allow type based dispatch only

Page 70: Functional OOP, Clojure style

Multi methods

• Polymorphism which is based on a user defined dispatching function

• The result of the execution of the dispatch function determines which implementation will be executes

Page 71: Functional OOP, Clojure style

(dispatch-fn)

take-care-of

::moon

::sun(tco-sun)

(tco-moon)

disp

atch

er

Page 72: Functional OOP, Clojure style

(dispatch-fn)

take-care-of

::moon

::sun(tco-sun)

(tco-moon)

This is the exposed API

disp

atch

er

Page 73: Functional OOP, Clojure style

(dispatch-fn)

take-care-of

::moon

::sun(tco-sun)

(tco-moon)

disp

atch

er

Page 74: Functional OOP, Clojure style

(dispatch-fn)

take-care-of

::moon

::sun(tco-sun)

(tco-moon)

disp

atch

er

Page 75: Functional OOP, Clojure style

(dispatch-fn)

take-care-of

::moon

::sun(tco-sun)

::lightning

(tco-lightning)

(tco-moon)

disp

atch

er

Page 76: Functional OOP, Clojure style
Page 77: Functional OOP, Clojure style

The multi method name

Page 78: Functional OOP, Clojure style

The dispatching function

Page 79: Functional OOP, Clojure style

Meanwhile, at other namespaces

Page 80: Functional OOP, Clojure style

Meanwhile, at other namespaces

Page 81: Functional OOP, Clojure style
Page 82: Functional OOP, Clojure style
Page 83: Functional OOP, Clojure style

Meanwhile, at other namespaces

Page 84: Functional OOP, Clojure style

Multi method

• We can use the same API for different data elements

• All we need to know is that they obey that API

• We can introduce new APIs for existing types

Page 85: Functional OOP, Clojure style

Multi method

• We can use the same API for different data elements

• All we need to know is that they obey that API

• We can introduce new APIs for existing types

Functional polymorphism

Page 86: Functional OOP, Clojure style

Is-a relationship

• We can define that A is-a B• The dispatcher would handle A the same

way that it handles B

• (derive ::A ::B)– if the dispatch function return ::A – if no value is found for ::A in the dispatcher– Handle it as ::B

Page 87: Functional OOP, Clojure style

Is-a relationship

Page 88: Functional OOP, Clojure style

Is-a relationship

Page 89: Functional OOP, Clojure style

Is-a relationship

Page 90: Functional OOP, Clojure style

Is-a relationship

Page 91: Functional OOP, Clojure style

Is-a relationship

Page 92: Functional OOP, Clojure style

Is-a relationship

Page 93: Functional OOP, Clojure style

Why did it work• Derive harms the referential transparency of the multi

method– The return value may differ if (derive…) was called – Referential transparency is our friend

• Derive works only with namespace bound keywords – Those that start with ::

• Clojure localizes the effect of mutability to the namespace

Page 94: Functional OOP, Clojure style

Type \ functionality

f1f2f3f4

T1XX

T2X

T3X

T4 XXXX

T4 isa T2 (for f2)

T4 isa T3 (for f3)

Page 95: Functional OOP, Clojure style

Type \ functionality

f1f2f3f4

T1XX

T2X

T3X

T4 XXXX

T4 isa T2 (for f2)

T4 isa T3 (for f3)

Functional inheritance

Page 96: Functional OOP, Clojure style

Summary

• We’ve seen– Functional abstraction– Functional information hiding– Functional polymorphism– Functional inheritance

Page 97: Functional OOP, Clojure style

Summary

• We’ve seen functional– Abstraction– Information hiding– Polymorphism– Inheritance

Page 98: Functional OOP, Clojure style

Summary

• We’ve seen functional OOP

Page 99: Functional OOP, Clojure style

Summary

• We’ve seen functional OOP

Clojure Style

Page 100: Functional OOP, Clojure style

Thank

You!


Recommended