SlideShare a Scribd company logo
declarative thinking,
declarative practice
@KevlinHenney
Computer Science in the 1960s to 80s
spent a lot of effort making languages
which were as powerful as possible.
Nowadays we have to appreciate the
reasons for picking not the most
powerful solution but the least powerful.
Tim Berners-Lee
https://www.w3.org/DesignIssues/Principles.html
The reason for this is that the less
powerful the language, the more you can
do with the data stored in that language.
If you write it in a simple declarative
form, anyone can write a program to
analyze it in many ways.
Tim Berners-Lee
https://www.w3.org/DesignIssues/Principles.html
The makefile language is similar
to declarative programming.
This class of language, in which
necessary end conditions are
described but the order in
which actions are to be taken is
not important, is sometimes
confusing to programmers used
to imperative programming.
http://en.wikipedia.org/wiki/Make_(software)
Representation
Is the Essence of
Programming
Show me your flowcharts and
conceal your tables, and I
shall continue to be mystified.
Show me your tables, and I
won’t usually need your
flowcharts; they’ll be obvious.
Excel is the world's
most popular
functional language.
Simon Peyton-Jones
try {
Integer.parseInt(time.substring(0, 2));
}
catch (Exception x) {
return false;
}
if (Integer.parseInt(time.substring(0, 2)) > 12) {
return false;
}
...
if (!time.substring(9, 11).equals("AM") &
!time.substring(9, 11).equals("PM")) {
return false;
}
Burk Hufnagel
"Put the Mouse Down and Step Away from the Keyboard"
Burk Hufnagel
"Put the Mouse Down and Step Away from the Keyboard"
public static boolean validateTime(String time) {
return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)");
}
Many programming languages support
programming in both functional and
imperative style but the syntax and
facilities of a language are typically
optimised for only one of these styles,
and social factors like coding conventions
and libraries often force the programmer
towards one of the styles.
https://wiki.haskell.org/Functional_programming
intension, n. (Logic)
 the set of characteristics or properties by which
the referent or referents of a given expression is
determined; the sense of an expression that
determines its reference in every possible world,
as opposed to its actual reference. For example,
the intension of prime number may be having
non-trivial integral factors, whereas its extension
would be the set {2, 3, 5, 7, ...}.
E J Borowski and J M Borwein
Dictionary of Mathematics
{ x2 | x  , x ≥ 1  x ≤ 100 }
select from where
A list comprehension is a syntactic
construct available in some programming
languages for creating a list based on
existing lists. It follows the form of the
mathematical set-builder notation (set
comprehension) as distinct from the use
of map and filter functions.
http://en.wikipedia.org/wiki/List_comprehension
{ x2 | x  , x ≥ 1 }
Lazy
evaluation
https://twitter.com/richardadalton/status/591534529086693376
def fizzbuzz(n):
result = ''
if n % 3 == 0:
result += 'Fizz'
if n % 5 == 0:
result += 'Buzz'
if not result:
result = str(n)
return result
def fizzbuzz(n):
if n % 15 == 0:
return 'FizzBuzz'
elif n % 3 == 0:
return 'Fizz'
elif n % 5 == 0:
return 'Buzz'
else:
return str(n)
def fizzbuzz(n):
return (
'FizzBuzz' if n % 15 == 0 else
'Fizz' if n % 3 == 0 else
'Buzz' if n % 5 == 0 else
str(n))
def fizzbuzz(n):
return (
'FizzBuzz' if n in range(0, 101, 15) else
'Fizz' if n in range(0, 101, 3) else
'Buzz' if n in range(0, 101, 5) else
str(n))
fizzes = [''] + ([''] * 2 + ['Fizz']) * 33 + ['']
buzzes = [''] + ([''] * 4 + ['Buzz']) * 20
numbers = list(map(str, range(0, 101)))
def fizzbuzz(n):
return fizzes[n] + buzzes[n] or numbers[n]
actual = [fizzbuzz(n) for n in range(1, 101)]
truths = [
every result is 'Fizz', 'Buzz', 'FizzBuzz' or a decimal string,
every decimal result corresponds to its ordinal position,
every third result contains 'Fizz',
every fifth result contains 'Buzz',
every fifteenth result is 'FizzBuzz',
the ordinal position of every 'Fizz' result is divisible by 3,
the ordinal position of every 'Buzz' result is divisible by 5,
the ordinal position of every 'FizzBuzz' result is divisible by 15
]
all(truths)
actual = [fizzbuzz(n) for n in range(1, 101)]
truths = [
all(a in {'Fizz', 'Buzz', 'FizzBuzz'} or a.isdecimal() for a in actual),
all(int(a) == n for n, a in enumerate(actual, 1) if a.isdecimal()),
all('Fizz' in a for a in actual[2::3]),
all('Buzz' in a for a in actual[4::5]),
all(a == 'FizzBuzz' for a in actual[14::15]),
all(n % 3 == 0 for n, a in enumerate(actual, 1) if a == 'Fizz'),
all(n % 5 == 0 for n, a in enumerate(actual, 1) if a == 'Buzz'),
all(n % 15 == 0 for n, a in enumerate(actual, 1) if a == 'FizzBuzz')
]
all(truths)
https://twitter.com/wm/status/7206700352
/ WordFriday
bi-quinary coded decimal, noun
 A system of representing numbers based on
counting in fives, with an additional indicator to
show whether the count is in the first or second half
of the decimal range, i.e., whether the number
represented is in the range 0–4 or 5–9.
 This system is found in many abacus systems, with
paired columns of counters (normally aligned)
representing each bi-quinary range.
 The Roman numeral system is also a form of bi-
quinary coded decimal.
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older?
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.limit(15)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.collect(toList()))
// Get the first 15 unique surnames in
// uppercase of the book authors that are 50
// years old or older.
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.limit(15)
.collect(toList()))
// Get the unique surnames in uppercase of the
// first 15 book authors that are 50 years old
// or older.
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.distinct()
.limit(15)
.map(Author::getSurname)
.map(String::toUpperCase)
.distinct()
.collect(toList()))
Simple filters that can be arbitrarily
chained are more easily re-used,
and more robust, than almost any
other kind of code.
Brandon Rhodes
http://rhodesmill.org/brandon/slides/2012-11-pyconca/
/ WordFriday
paraskevidekatriaphobia, noun
 The superstitious fear of Friday 13th.
 Contrary to popular myth, this superstition is
relatively recent (19th century) and did not originate
during or before the medieval times.
 Paraskevidekatriaphobia also reflects a particularly
egocentric attributional bias: the universe is
prepared to rearrange causality and probability
around the believer based on an arbitrary and
changeable calendar system, in a way that is
sensitive to geography, culture and time zone.
function NextFriday13thAfter($from) {
(1..500) |
%{ $from.AddDays($_) } |
?{ $_.Day -eq 13} |
?{ $_.DayOfWeek -eq [DayOfWeek]::Friday } |
select –first 1
}
Stack
Stack
{push, pop, depth, top}
Stack[T]
{
push(T),
pop(),
depth() : Integer,
top() : T
}
An interface is a contract to deliver
a certain amount of service.
Clients of the interface depend on
the contract, which is usually
documented in the interface
specification.
Butler W Lampson
"Hints for Computer System Design"
Stack[T]
{
push(T item),
pop(),
depth() : Integer,
top() : T
}
given:
before = depth()
postcondition:
depth() = before + 1 ∧ top() = item
precondition:
depth() > 0
given:
before = depth()
precondition:
before > 0
postcondition:
depth() = before – 1
given:
result = depth()
postcondition:
result ≥ 0
alphabet(Stack) =
{push, pop, depth, top}
trace(Stack) =
{⟨ ⟩,
⟨push⟩, ⟨depth⟩,
⟨push, pop⟩, ⟨push, top⟩,
⟨push, depth⟩, ⟨push, push⟩,
⟨depth, push⟩, ⟨depth, depth⟩,
⟨push, push, pop⟩,
...}
Non-EmptyEmpty
depth depth
top
push
pop [depth > 1]
push
pop [depth = 1]
public class Stack_spec
{
public static class A_new_stack
{
@Test
public void has_no_depth() 
@Test()
public void has_no_top() 
}
public static class An_empty_stack
{
@Test()
public void throws_when_popped() 
@Test
public void acquires_depth_by_retaining_a_pushed_item_as_its_top() 
}
public static class A_non_empty_stack
{
@Test
public void becomes_deeper_by_retaining_a_pushed_item_as_its_top() 
@Test
public void on_popping_reveals_tops_in_reverse_order_of_pushing() 
}
}
public class
Stack_spec
{
public static class
A_new_stack
{
@Test
public void has_no_depth() 
@Test()
public void has_no_top() 
}
public static class
An_empty_stack
{
@Test()
public void throws_when_popped() 
@Test
public void acquires_depth_by_retaining_a_pushed_item_as_its_top() 
}
public static class
A_non_empty_stack
{
@Test
public void becomes_deeper_by_retaining_a_pushed_item_as_its_top() 
@Test
public void on_popping_reveals_tops_in_reverse_order_of_pushing() 
}
}
public class
Stack_spec
{
public static class
A_new_stack
{
@Test
public void has_no_depth() 
@Test()
public void has_no_top() 
}
public static class
An_empty_stack
{
@Test()
public void throws_when_popped() 
@Test
public void acquires_depth_by_retaining_a_pushed_item_as_its_top() 
}
public static class
A_non_empty_stack
{
@Test
public void becomes_deeper_by_retaining_a_pushed_item_as_its_top() 
@Test
public void on_popping_reveals_tops_in_reverse_order_of_pushing() 
}
}
Propositions
are vehicles
for stating
how things are
or might be.
Thus only indicative
sentences which it
makes sense to think
of as being true or as
being false are
capable of expressing
propositions.
































{P} S {Q}
Are human beings
"noble in reason" and
"infinite in faculty" as
William Shakespeare
famously wrote?
Perfect, "in God's
image," as some
biblical scholars have
asserted?
Hardly.
def is_leap_year(year):
...
# What is the postcondition?
def is_leap_year(year):
...
# Given
# result = is_leap_year(year)
# Then
# result == (
# year % 4 == 0 and
# year % 100 != 0 or
# year % 400 == 0)
def is_leap_year(year):
return (
year % 4 == 0 and
year % 100 != 0 or
year % 400 == 0)
def test_is_leap_year():
...
def test_is_leap_year_works():
...
Express intention
of code usage
with respect to data
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
def test(function):
function.is_test = True
return function
def check(suite):
tests = [
attr
for attr in (getattr(suite, name) for name in dir(suite))
if callable(attr) and hasattr(attr, 'is_test')]
for to_test in tests:
try:
to_test(suite())
except:
print('Failed: ' + to_test.__name__ + '()')
Express intention
of code usage
with respect to data
Express intention
Naming
Grouping and nesting
of code usage
Realisation of intent
with respect to data
One exemplar or many
Explicit or generated
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
assert not is_leap_year(1999)
assert not is_leap_year(1)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
assert not is_leap_year(1999)
assert not is_leap_year(1)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
assert is_leap_year(1984)
assert is_leap_year(4)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
assert not is_leap_year(1999)
assert not is_leap_year(1)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
assert is_leap_year(1984)
assert is_leap_year(4)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
for year in range(400, 2401, 400):
assert is_leap_year(year)
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
assert not is_leap_year(1999)
assert not is_leap_year(1)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
assert is_leap_year(1984)
assert is_leap_year(4)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
for year in range(100, 2101, 100):
if year % 400 != 0:
assert not is_leap_year(year)
@test
def years_divisible_by_400_are_leap_years(self):
for year in range(400, 2401, 400):
assert is_leap_year(year)
class LeapYearSpec:
@test
def years_not_divisible_by_4_are_not_leap_years(self):
assert not is_leap_year(2015)
assert not is_leap_year(1999)
assert not is_leap_year(1)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
assert is_leap_year(1984)
assert is_leap_year(4)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
for year in range(100, 2101, 100):
if year % 400 != 0:
assert not is_leap_year(year)
@test
def years_divisible_by_400_are_leap_years(self):
for year in range(400, 2401, 400):
assert is_leap_year(year)
def test(function):
function.is_test = True
return function
def data(*values):
def prepender(function):
function.data = values + getattr(function, 'data', ())
return function
return prepender
def check(suite):
tests = [
attr
for attr in (getattr(suite, name) for name in dir(suite))
if callable(attr) and hasattr(attr, 'is_test')]
for to_test in tests:
try:
if hasattr(to_test, 'data'):
for value in to_test.data:
call = '(' + str(value) + ')'
to_test(suite(), value)
else:
call = '()'
to_test(suite())
except:
print('Failed: ' + to_test.__name__ + call)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
def years_divisible_by_4_but_not_by_100_are_leap_years(self):
assert is_leap_year(2016)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
def years_divisible_by_400_are_leap_years(self):
assert is_leap_year(2000)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self):
assert not is_leap_year(1900)
@test
@data(*range(400, 2401, 400))
def years_divisible_by_400_are_leap_years(self, year):
assert is_leap_year(year)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
@data(*(year for year in range(100, 2101, 100) if year % 400 != 0))
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(*range(400, 2401, 400))
def years_divisible_by_400_are_leap_years(self, year):
assert is_leap_year(year)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
@data(*range(100, 2101, 400))
@data(*range(200, 2101, 400))
@data(*range(300, 2101, 400))
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(*range(400, 2401, 400))
def years_divisible_by_400_are_leap_years(self, year):
assert is_leap_year(year)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
@data(*range(100, 2101, 400))
@data(*range(200, 2101, 400))
@data(*range(300, 2101, 400))
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(*range(400, 2401, 400))
def years_divisible_by_400_are_leap_years(self, year):
assert is_leap_year(year)
class LeapYearSpec:
@test
@data(2015)
@data(1999)
@data(1)
def years_not_divisible_by_4_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(2016, 1984, 4)
def years_divisible_by_4_but_not_by_100_are_leap_years(self, year):
assert is_leap_year(year)
@test
@data(*range(100, 2101, 400))
@data(*range(200, 2101, 400))
@data(*range(300, 2101, 400))
def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year):
assert not is_leap_year(year)
@test
@data(*range(400, 2401, 400))
def years_divisible_by_400_are_leap_years(self, year):
assert is_leap_year(year)
Express intention
Naming
Grouping and nesting
of code usage
Realisation of intent
with respect to data
One exemplar or many
Explicit or generated
intention
declaration
of intent
Our task is not to find the
maximum amount of
content in a work of art.
Our task is to cut back
content so that we can see
the thing at all.
Susan Sontag

More Related Content

What's hot

Python Cheat Sheet
Python Cheat SheetPython Cheat Sheet
Python Cheat Sheet
Muthu Vinayagam
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
Paige Bailey
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)
Pedro Rodrigues
 
Functions in python
Functions in pythonFunctions in python
Functions in pythonIlian Iliev
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
Python Puzzlers - 2016 Edition
Python Puzzlers - 2016 EditionPython Puzzlers - 2016 Edition
Python Puzzlers - 2016 Edition
Nandan Sawant
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2
RajKumar Rampelli
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
Ganesh Samarthyam
 
Python
PythonPython
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
Philip Schwarz
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Bryan O'Sullivan
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
Marian Marinov
 
Real World Haskell: Lecture 6
Real World Haskell: Lecture 6Real World Haskell: Lecture 6
Real World Haskell: Lecture 6Bryan O'Sullivan
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
Rick Copeland
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
Norman Richards
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Declare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term RewritingDeclare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term Rewriting
Eelco Visser
 
Declarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term RewritingDeclarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term Rewriting
Guido Wachsmuth
 
07. Java Array, Set and Maps
07.  Java Array, Set and Maps07.  Java Array, Set and Maps
07. Java Array, Set and Maps
Intro C# Book
 

What's hot (20)

Python Cheat Sheet
Python Cheat SheetPython Cheat Sheet
Python Cheat Sheet
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)
 
Functions in python
Functions in pythonFunctions in python
Functions in python
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Python Puzzlers - 2016 Edition
Python Puzzlers - 2016 EditionPython Puzzlers - 2016 Edition
Python Puzzlers - 2016 Edition
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Python
PythonPython
Python
 
The Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 
Real World Haskell: Lecture 1
Real World Haskell: Lecture 1Real World Haskell: Lecture 1
Real World Haskell: Lecture 1
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
Real World Haskell: Lecture 6
Real World Haskell: Lecture 6Real World Haskell: Lecture 6
Real World Haskell: Lecture 6
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Declare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term RewritingDeclare Your Language: Transformation by Strategic Term Rewriting
Declare Your Language: Transformation by Strategic Term Rewriting
 
Declarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term RewritingDeclarative Semantics Definition - Term Rewriting
Declarative Semantics Definition - Term Rewriting
 
07. Java Array, Set and Maps
07.  Java Array, Set and Maps07.  Java Array, Set and Maps
07. Java Array, Set and Maps
 

Similar to Declarative Thinking, Declarative Practice

Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)
Guy Lebanon
 
Python programming workshop
Python programming workshopPython programming workshop
Python programming workshop
BAINIDA
 
Poetry with R -- Dissecting the code
Poetry with R -- Dissecting the codePoetry with R -- Dissecting the code
Poetry with R -- Dissecting the code
Peter Solymos
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
carliotwaycave
 
Morel, a data-parallel programming language
Morel, a data-parallel programming languageMorel, a data-parallel programming language
Morel, a data-parallel programming language
Julian Hyde
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
vsssuresh
 
Python.pdf
Python.pdfPython.pdf
Python.pdf
Shivakumar B N
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Muthu Vinayagam
 
Functional Programming in F#
Functional Programming in F#Functional Programming in F#
Functional Programming in F#Dmitri Nesteruk
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
Tapio Rautonen
 
Introduction to R programming
Introduction to R programmingIntroduction to R programming
Introduction to R programming
Alberto Labarga
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a MomentSergio Gil
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
Presentation R basic teaching module
Presentation R basic teaching modulePresentation R basic teaching module
Presentation R basic teaching module
Sander Timmer
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
Software Guru
 
R language introduction
R language introductionR language introduction
R language introduction
Shashwat Shriparv
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao
 
Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
University of Salerno
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
Eelco Visser
 
Lecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptxLecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
 

Similar to Declarative Thinking, Declarative Practice (20)

Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)
 
Python programming workshop
Python programming workshopPython programming workshop
Python programming workshop
 
Poetry with R -- Dissecting the code
Poetry with R -- Dissecting the codePoetry with R -- Dissecting the code
Poetry with R -- Dissecting the code
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
 
Morel, a data-parallel programming language
Morel, a data-parallel programming languageMorel, a data-parallel programming language
Morel, a data-parallel programming language
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Python.pdf
Python.pdfPython.pdf
Python.pdf
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
Functional Programming in F#
Functional Programming in F#Functional Programming in F#
Functional Programming in F#
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
Introduction to R programming
Introduction to R programmingIntroduction to R programming
Introduction to R programming
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
Presentation R basic teaching module
Presentation R basic teaching modulePresentation R basic teaching module
Presentation R basic teaching module
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
 
R language introduction
R language introductionR language introduction
R language introduction
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
 
Lecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptxLecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptx
 

More from Kevlin Henney

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
Kevlin Henney
 
Get Kata
Get KataGet Kata
Get Kata
Kevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
Kevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
Kevlin Henney
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
Kevlin Henney
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
Kevlin Henney
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Kevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
 

Recently uploaded

Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
Srikant77
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Jay Das
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 

Recently uploaded (20)

Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 

Declarative Thinking, Declarative Practice

  • 2.
  • 3.
  • 4. Computer Science in the 1960s to 80s spent a lot of effort making languages which were as powerful as possible. Nowadays we have to appreciate the reasons for picking not the most powerful solution but the least powerful. Tim Berners-Lee https://www.w3.org/DesignIssues/Principles.html
  • 5. The reason for this is that the less powerful the language, the more you can do with the data stored in that language. If you write it in a simple declarative form, anyone can write a program to analyze it in many ways. Tim Berners-Lee https://www.w3.org/DesignIssues/Principles.html
  • 6.
  • 7. The makefile language is similar to declarative programming. This class of language, in which necessary end conditions are described but the order in which actions are to be taken is not important, is sometimes confusing to programmers used to imperative programming. http://en.wikipedia.org/wiki/Make_(software)
  • 8.
  • 9.
  • 10.
  • 12. Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious.
  • 13. Excel is the world's most popular functional language. Simon Peyton-Jones
  • 14. try { Integer.parseInt(time.substring(0, 2)); } catch (Exception x) { return false; } if (Integer.parseInt(time.substring(0, 2)) > 12) { return false; } ... if (!time.substring(9, 11).equals("AM") & !time.substring(9, 11).equals("PM")) { return false; } Burk Hufnagel "Put the Mouse Down and Step Away from the Keyboard"
  • 15. Burk Hufnagel "Put the Mouse Down and Step Away from the Keyboard" public static boolean validateTime(String time) { return time.matches("(0[1-9]|1[0-2]):[0-5][0-9]:[0-5][0-9] ([AP]M)"); }
  • 16. Many programming languages support programming in both functional and imperative style but the syntax and facilities of a language are typically optimised for only one of these styles, and social factors like coding conventions and libraries often force the programmer towards one of the styles. https://wiki.haskell.org/Functional_programming
  • 17.
  • 18.
  • 19.
  • 20. intension, n. (Logic)  the set of characteristics or properties by which the referent or referents of a given expression is determined; the sense of an expression that determines its reference in every possible world, as opposed to its actual reference. For example, the intension of prime number may be having non-trivial integral factors, whereas its extension would be the set {2, 3, 5, 7, ...}. E J Borowski and J M Borwein Dictionary of Mathematics
  • 21. { x2 | x  , x ≥ 1  x ≤ 100 } select from where
  • 22. A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical set-builder notation (set comprehension) as distinct from the use of map and filter functions. http://en.wikipedia.org/wiki/List_comprehension
  • 23.
  • 24. { x2 | x  , x ≥ 1 }
  • 25.
  • 27.
  • 29. def fizzbuzz(n): result = '' if n % 3 == 0: result += 'Fizz' if n % 5 == 0: result += 'Buzz' if not result: result = str(n) return result
  • 30. def fizzbuzz(n): if n % 15 == 0: return 'FizzBuzz' elif n % 3 == 0: return 'Fizz' elif n % 5 == 0: return 'Buzz' else: return str(n)
  • 31. def fizzbuzz(n): return ( 'FizzBuzz' if n % 15 == 0 else 'Fizz' if n % 3 == 0 else 'Buzz' if n % 5 == 0 else str(n))
  • 32. def fizzbuzz(n): return ( 'FizzBuzz' if n in range(0, 101, 15) else 'Fizz' if n in range(0, 101, 3) else 'Buzz' if n in range(0, 101, 5) else str(n))
  • 33. fizzes = [''] + ([''] * 2 + ['Fizz']) * 33 + [''] buzzes = [''] + ([''] * 4 + ['Buzz']) * 20 numbers = list(map(str, range(0, 101))) def fizzbuzz(n): return fizzes[n] + buzzes[n] or numbers[n]
  • 34. actual = [fizzbuzz(n) for n in range(1, 101)] truths = [ every result is 'Fizz', 'Buzz', 'FizzBuzz' or a decimal string, every decimal result corresponds to its ordinal position, every third result contains 'Fizz', every fifth result contains 'Buzz', every fifteenth result is 'FizzBuzz', the ordinal position of every 'Fizz' result is divisible by 3, the ordinal position of every 'Buzz' result is divisible by 5, the ordinal position of every 'FizzBuzz' result is divisible by 15 ] all(truths)
  • 35. actual = [fizzbuzz(n) for n in range(1, 101)] truths = [ all(a in {'Fizz', 'Buzz', 'FizzBuzz'} or a.isdecimal() for a in actual), all(int(a) == n for n, a in enumerate(actual, 1) if a.isdecimal()), all('Fizz' in a for a in actual[2::3]), all('Buzz' in a for a in actual[4::5]), all(a == 'FizzBuzz' for a in actual[14::15]), all(n % 3 == 0 for n, a in enumerate(actual, 1) if a == 'Fizz'), all(n % 5 == 0 for n, a in enumerate(actual, 1) if a == 'Buzz'), all(n % 15 == 0 for n, a in enumerate(actual, 1) if a == 'FizzBuzz') ] all(truths)
  • 36.
  • 37.
  • 38.
  • 41. bi-quinary coded decimal, noun  A system of representing numbers based on counting in fives, with an additional indicator to show whether the count is in the first or second half of the decimal range, i.e., whether the number represented is in the range 0–4 or 5–9.  This system is found in many abacus systems, with paired columns of counters (normally aligned) representing each bi-quinary range.  The Roman numeral system is also a form of bi- quinary coded decimal.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older? library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList()))
  • 49. // Get the first 15 unique surnames in // uppercase of the book authors that are 50 // years old or older. library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .limit(15) .collect(toList()))
  • 50. // Get the unique surnames in uppercase of the // first 15 book authors that are 50 years old // or older. library.stream() .map(book -> book.getAuthor()) .filter(author -> author.getAge() >= 50) .distinct() .limit(15) .map(Author::getSurname) .map(String::toUpperCase) .distinct() .collect(toList()))
  • 51. Simple filters that can be arbitrarily chained are more easily re-used, and more robust, than almost any other kind of code. Brandon Rhodes http://rhodesmill.org/brandon/slides/2012-11-pyconca/
  • 53. paraskevidekatriaphobia, noun  The superstitious fear of Friday 13th.  Contrary to popular myth, this superstition is relatively recent (19th century) and did not originate during or before the medieval times.  Paraskevidekatriaphobia also reflects a particularly egocentric attributional bias: the universe is prepared to rearrange causality and probability around the believer based on an arbitrary and changeable calendar system, in a way that is sensitive to geography, culture and time zone.
  • 54.
  • 55. function NextFriday13thAfter($from) { (1..500) | %{ $from.AddDays($_) } | ?{ $_.Day -eq 13} | ?{ $_.DayOfWeek -eq [DayOfWeek]::Friday } | select –first 1 }
  • 56.
  • 57.
  • 58.
  • 59. Stack
  • 62. An interface is a contract to deliver a certain amount of service. Clients of the interface depend on the contract, which is usually documented in the interface specification. Butler W Lampson "Hints for Computer System Design"
  • 63.
  • 64. Stack[T] { push(T item), pop(), depth() : Integer, top() : T } given: before = depth() postcondition: depth() = before + 1 ∧ top() = item precondition: depth() > 0 given: before = depth() precondition: before > 0 postcondition: depth() = before – 1 given: result = depth() postcondition: result ≥ 0
  • 65.
  • 67. trace(Stack) = {⟨ ⟩, ⟨push⟩, ⟨depth⟩, ⟨push, pop⟩, ⟨push, top⟩, ⟨push, depth⟩, ⟨push, push⟩, ⟨depth, push⟩, ⟨depth, depth⟩, ⟨push, push, pop⟩, ...}
  • 69. public class Stack_spec { public static class A_new_stack { @Test public void has_no_depth()  @Test() public void has_no_top()  } public static class An_empty_stack { @Test() public void throws_when_popped()  @Test public void acquires_depth_by_retaining_a_pushed_item_as_its_top()  } public static class A_non_empty_stack { @Test public void becomes_deeper_by_retaining_a_pushed_item_as_its_top()  @Test public void on_popping_reveals_tops_in_reverse_order_of_pushing()  } }
  • 70. public class Stack_spec { public static class A_new_stack { @Test public void has_no_depth()  @Test() public void has_no_top()  } public static class An_empty_stack { @Test() public void throws_when_popped()  @Test public void acquires_depth_by_retaining_a_pushed_item_as_its_top()  } public static class A_non_empty_stack { @Test public void becomes_deeper_by_retaining_a_pushed_item_as_its_top()  @Test public void on_popping_reveals_tops_in_reverse_order_of_pushing()  } }
  • 71. public class Stack_spec { public static class A_new_stack { @Test public void has_no_depth()  @Test() public void has_no_top()  } public static class An_empty_stack { @Test() public void throws_when_popped()  @Test public void acquires_depth_by_retaining_a_pushed_item_as_its_top()  } public static class A_non_empty_stack { @Test public void becomes_deeper_by_retaining_a_pushed_item_as_its_top()  @Test public void on_popping_reveals_tops_in_reverse_order_of_pushing()  } }
  • 72.
  • 73. Propositions are vehicles for stating how things are or might be.
  • 74. Thus only indicative sentences which it makes sense to think of as being true or as being false are capable of expressing propositions.
  • 75.
  • 82.
  • 84.
  • 85.
  • 86. Are human beings "noble in reason" and "infinite in faculty" as William Shakespeare famously wrote? Perfect, "in God's image," as some biblical scholars have asserted?
  • 88. def is_leap_year(year): ... # What is the postcondition?
  • 89. def is_leap_year(year): ... # Given # result = is_leap_year(year) # Then # result == ( # year % 4 == 0 and # year % 100 != 0 or # year % 400 == 0)
  • 90. def is_leap_year(year): return ( year % 4 == 0 and year % 100 != 0 or year % 400 == 0)
  • 93. Express intention of code usage with respect to data
  • 94. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 95. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 96. def test(function): function.is_test = True return function def check(suite): tests = [ attr for attr in (getattr(suite, name) for name in dir(suite)) if callable(attr) and hasattr(attr, 'is_test')] for to_test in tests: try: to_test(suite()) except: print('Failed: ' + to_test.__name__ + '()')
  • 97. Express intention of code usage with respect to data
  • 98. Express intention Naming Grouping and nesting of code usage Realisation of intent with respect to data One exemplar or many Explicit or generated
  • 99. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) assert not is_leap_year(1999) assert not is_leap_year(1) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 100. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) assert not is_leap_year(1999) assert not is_leap_year(1) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) assert is_leap_year(1984) assert is_leap_year(4) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 101. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) assert not is_leap_year(1999) assert not is_leap_year(1) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) assert is_leap_year(1984) assert is_leap_year(4) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): for year in range(400, 2401, 400): assert is_leap_year(year)
  • 102. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) assert not is_leap_year(1999) assert not is_leap_year(1) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) assert is_leap_year(1984) assert is_leap_year(4) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): for year in range(100, 2101, 100): if year % 400 != 0: assert not is_leap_year(year) @test def years_divisible_by_400_are_leap_years(self): for year in range(400, 2401, 400): assert is_leap_year(year)
  • 103. class LeapYearSpec: @test def years_not_divisible_by_4_are_not_leap_years(self): assert not is_leap_year(2015) assert not is_leap_year(1999) assert not is_leap_year(1) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) assert is_leap_year(1984) assert is_leap_year(4) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): for year in range(100, 2101, 100): if year % 400 != 0: assert not is_leap_year(year) @test def years_divisible_by_400_are_leap_years(self): for year in range(400, 2401, 400): assert is_leap_year(year)
  • 104. def test(function): function.is_test = True return function def data(*values): def prepender(function): function.data = values + getattr(function, 'data', ()) return function return prepender def check(suite): tests = [ attr for attr in (getattr(suite, name) for name in dir(suite)) if callable(attr) and hasattr(attr, 'is_test')] for to_test in tests: try: if hasattr(to_test, 'data'): for value in to_test.data: call = '(' + str(value) + ')' to_test(suite(), value) else: call = '()' to_test(suite()) except: print('Failed: ' + to_test.__name__ + call)
  • 105. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test def years_divisible_by_4_but_not_by_100_are_leap_years(self): assert is_leap_year(2016) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 106. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test def years_divisible_by_400_are_leap_years(self): assert is_leap_year(2000)
  • 107. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test def years_divisible_by_100_but_not_by_400_are_not_leap_years(self): assert not is_leap_year(1900) @test @data(*range(400, 2401, 400)) def years_divisible_by_400_are_leap_years(self, year): assert is_leap_year(year)
  • 108. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test @data(*(year for year in range(100, 2101, 100) if year % 400 != 0)) def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(*range(400, 2401, 400)) def years_divisible_by_400_are_leap_years(self, year): assert is_leap_year(year)
  • 109. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test @data(*range(100, 2101, 400)) @data(*range(200, 2101, 400)) @data(*range(300, 2101, 400)) def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(*range(400, 2401, 400)) def years_divisible_by_400_are_leap_years(self, year): assert is_leap_year(year)
  • 110. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test @data(*range(100, 2101, 400)) @data(*range(200, 2101, 400)) @data(*range(300, 2101, 400)) def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(*range(400, 2401, 400)) def years_divisible_by_400_are_leap_years(self, year): assert is_leap_year(year)
  • 111. class LeapYearSpec: @test @data(2015) @data(1999) @data(1) def years_not_divisible_by_4_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(2016, 1984, 4) def years_divisible_by_4_but_not_by_100_are_leap_years(self, year): assert is_leap_year(year) @test @data(*range(100, 2101, 400)) @data(*range(200, 2101, 400)) @data(*range(300, 2101, 400)) def years_divisible_by_100_but_not_by_400_are_not_leap_years(self, year): assert not is_leap_year(year) @test @data(*range(400, 2401, 400)) def years_divisible_by_400_are_leap_years(self, year): assert is_leap_year(year)
  • 112. Express intention Naming Grouping and nesting of code usage Realisation of intent with respect to data One exemplar or many Explicit or generated
  • 115. Our task is not to find the maximum amount of content in a work of art. Our task is to cut back content so that we can see the thing at all. Susan Sontag