88

mph
YEAR
2016
GitHub
YEAR
440 BCE
Herodotus
“Herodotus of
Halicarnassus here
presents his research
so that human events
do not fade with
time.”
Herodotus, The Histories

Book I, Proem

trans. Andrea L. Purvis

YEAR
404 BCE
Lysander
“[Sparta] they would never
reduce to slavery a city
which was itself an integral
portion of Hellas, and had
performed a great and
noble service to Hellas in
the most perilous of
emergencies.”
Xenophon, Hellenica

Book 2, 2.20

trans. H. G. Dakyns

YEAR
399 BCE
Socrates
“[Writing offers readers] the
appearance of wisdom, not true
wisdom, for they will read many
things without instruction and
will therefore seem to know
many things, when they are for
the most part ignorant and hard
to get along with, since they are
not wise, but only appear wise.”
Plato, Phaedrus
275a-b

trans. Harold N. Fowler

YEAR
1822
Hegel
“World history is
the record of the
spirit's efforts to
attain knowledge of
what it is in itself.”
Hegel, Lectures on the
Philosophy of World History

Introduction

trans. Johannes Hoffmeister

Timeline
• Local Functions
• Tuples
• Records
• Pattern Matching
• Ref Locals / Ref Returns
• Binary Literals / Digit Separators
Timeline
• Local Functions
• Tuples
• Pattern Matching
Timeline
• Local Functions
• Tuples
• Pattern Matching
YEAR
1960
Algol 60
Local Functions

{Algol 60}
begin
comment classic recursive procedure;
integer nn, nf;
integer procedure factorial(n); value n; integer n;
begin
if n <= 1 then factorial := 1
else factorial := n * factorial(n-1)
end;
nn := 5;
nf := factorial(nn);
outinteger ( 1 , nf)
end
taken from: http://algol60.org/lego/procedure11.a60Algol 60
Local Functions

{Algol 60}
integer procedure factorial(n); value n; integer n;
begin
if n <= 1 then factorial := 1
else factorial := n * factorial(n-1)
end;
nn := 5;
nf := factorial(nn);
taken from: http://algol60.org/lego/procedure11.a60Algol 60
YEAR
2015
C# 6
Local Functions

{without language support}
private struct locals
{
public int x;
}
static void Main(string[] args)
{
var x = 42;
var local = new locals {x = x};
AddOne(ref local);
x = local.x;
WriteLine($"x + 1 = {x}");
}
private static void AddOne(ref locals implicits)
{
implicits.x += 1;
}
C# 6
YEAR
2017
C# 7
Local Functions

{with language support}
static void Main(string[] args)
{
var x = 42;
void AddOne()
{
x += 1;
}
AddOne();
WriteLine($"x + 1 = {x}");
}
C# 7
Functions
Functions

{basic}
function outputinput
Functions

{real world}
function
outputinput
effect
side

effect
Functions

{basic}
Hello Lengthname
Functions

{basic}
public int Hello(string name)
{
var time = DateTime.Now;
Console.Write($"Hello {name} it is now {time}");
return name.Length;
}
C# 6
Functions

{real world}
Hello
Lengthname
DateTime Console
Functions

{real world}
public int Hello(string name)
{
var time = DateTime.Now;
Console.Write($"Hello {name} it is now {time}");
return name.Length;
}
C# 6
YEAR
2017
C# 7
Local Functions

{“realistic”}
static void Main(string[] args)
{
var program = new Program();
IEnumerable<int> values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string FormatValues()
{
return string.Join(",", values);
}
Console.WriteLine($"before: {FormatValues()}");
values = program.RealistCode(values);
Console.WriteLine($"after: {FormatValues()}");
}
public IEnumerable<int> RealistCode(IEnumerable<int> values)
{
if (values == null)
throw new ArgumentException("values cannot be null");
if (!values.Any())
throw new ArgumentException("must have at least one element in values");
IEnumerable <int> Rules()
{
return values
.Where(x => x > 2)
.Where(x => x%2 == 1);
}
return Rules();
}
C# 7
Local Functions

{“realistic”}
static void Main(string[] args)
{
var program = new Program();
IEnumerable<int> values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string FormatValues()
{
return string.Join(",", values);
}
Console.WriteLine($"before: {FormatValues()}");
values = program.RealistCode(values);
Console.WriteLine($"after: {FormatValues()}");
}
C# 7
Local Functions

{really “realistic”}
public IEnumerable<int> RealistCode(IEnumerable<int> values)
{
if (values == null)
throw new ArgumentException("values cannot be null");
if (!values.Any())
throw new ArgumentException(
"must have at least one element in values");
IEnumerable <int> Rules()
{
return values
.Where(x => x > 2)
.Where(x => x%2 == 1);
}
return Rules();
}
C# 7
Local Functions

{really “realistic”}
public IEnumerable<int> RealistCode(IEnumerable<int> values)
{
Precondition();
return values
.Where(x => x > 2)
.Where(x => x%2 == 1);
void Precondition()
{
if (values == null)
throw new ArgumentException("values cannot be null");
if (!values.Any())
throw new ArgumentException("must have at least one element in values");
}
}
C# 7
Design

By Contract
YEAR
1985
Eiffel
Local Functions

{design by contract}
note
description : "example of factorial"
class
APPLICATION
create
make
feature -- Initialization
make
local
n: NATURAL
do
n := 3
print ("%NFactorial of " + n.out + " = ")
print (recursive_factorial (n))
end
feature -- Access
recursive_factorial (n: NATURAL): NATURAL
require
n >= 0
do
if n = 0 then
Result := 1
else
Result := n * recursive_factorial (n - 1)
end
end
end
Eiffel
Local Functions

{design by contract}
feature -- Access
recursive_factorial (n: NATURAL): NATURAL
require
n >= 0
do
if n = 0 then
Result := 1
else
Result := n * recursive_factorial (n - 1)
end
end
end
Eiffel
YEAR
2009
Clojure
Local Functions

{design by contract}
(ns com.blogspot.comp-phil.factorial)
;; no tail call optimization
(defn factorial [n]
{:pre [((comp not neg?) n)]}
(if (= n 0)
1
(* n (factorial (dec n)))))
(factorial 1)
(factorial 5)
Clojure
Local Functions

{design by contract}
(defn factorial [n]
{:pre [((comp not neg?) n)]}
(if (= n 0)
1
(* n (factorial (dec n)))))
Clojure
YEAR
2017
C# 7
Local Functions

{design by contract}
static void Main(string[] args)
{
// no tail call optimization
long Factorial(int x)
{
if (x < 0)
throw new ArgumentException(“value < 0”);
if (x <= 1) return 1;
return x * Factorial(x-1);
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Tail Call

Optimization
YEAR
2017
C# 7
Local Functions

{no tail call}
static void Main(string[] args)
{
// no tail call optimization
long Factorial(int x)
{
if (x <= 1) return 1;
return x * Factorial(x-1);
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
long Factorial(int x)
{
if (x <= 1) return x;
return x * Factorial(x-1);
}
x = 3

3 * ?
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
long Factorial(int x)
{
if (x <= 1) return x;
return x * Factorial(x-1);
}
x = 3

3 *
x = 2

2 * ?
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
x = 3

3 *
long Factorial(int x)
{
if (x <= 1) return x;
return x * Factorial(x-1);
}
x = 2

2 *
x = 1

1
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
x = 3

3 *
long Factorial(int x)
{
if (x <= 1) return x;
return x * Factorial(x-1);
}
x = 2

2
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
x = 3

6
long Factorial(int x)
{
if (x <= 1) return x;
return x * Factorial(x-1);
}
C# 7
Local Functions

{tail call}
static void Main(string[] args)
{
// would have tail call optimization if supported
long Factorial(int x)
{
long Aux(long acc, int n)
{
if (n <= 1) return acc;
return Aux(acc * n, n - 1);
}
return Aux(1, x);
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 1

n = 3
long Aux(long acc, int n)
{
if (n <= 1) return acc;
return Aux(acc * n, n - 1);
}
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 1

n = 3
acc = 3

n = 2
long Aux(long acc, int n)
{
if (n <= 1) return acc;
return Aux(acc * n, n - 1);
}
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 1

n = 3
acc = 3

n = 2
acc = 6

n = 1
long Aux(long acc, int n)
{
if (n <= 1) return acc;
return Aux(acc * n, n - 1);
}
C# 7
Local Functions

{“tail call optimization”}
static void Main(string[] args)
{
// simulated tail call optimization
long Factorial(int n)
{
long acc = 1;
top:
if (n <= 1) return acc;
acc *= n;
n--;
goto top;
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Local Functions

{“tail call optimization”}
static void Main(string[] args)
{
// simulated tail call optimization
long Factorial(int n)
{
long acc = 1;
top:
if (n <= 1) return acc;
acc *= n;
n--;
goto top;
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 1

n = 3
long Factorial(int n)
{
long acc = 1;
top:
if (n <= 1) return acc;
acc *= n;
n--;
goto top;
}C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 3

n = 2
long Factorial(int n)
{
long acc = 1;
top:
if (n <= 1) return acc;
acc *= n;
n--;
goto top;
}C# 7
Console.WriteLine($"3! = {Factorial(3)}");
acc = 6

n = 1
long Factorial(int n)
{
long acc = 1;
top:
if (n <= 1) return acc;
acc *= n;
n--;
goto top;
}C# 7
YEAR
2010
F#
Local Functions

{tail call optimization}
F#
module Factorial =
let factorial x =
let rec aux m x =
match x with
| 0 -> m
| _ -> aux (m*x) (x-1)
aux 1 x
Timeline
• Local Functions
• Tuples
• Pattern Matching
Tuples
tuple
item 1 item 2
Tuples
“Hello” 42
YEAR
2010
C# 4.0
Tuple

{mostly everything}
static void Main(string[] args)
{
Console.WriteLine("1! = “ + Factorial(1));
Console.WriteLine("5! = “ + Factorial(5));
Console.WriteLine("20! = “ + Factorial(20));
}
private static long Factorial(int x)
{
return FactorialAux(new Tuple<int, int>(1, x));
}
private static long FactorialAux(Tuple<int, int> t)
{
if (t.Item2 <= 1) return t.Item1;
var r = new Tuple<int, int>(t.Item1*t.Item2, t.Item2 - 1);
return FactorialAux(r);
}
C# 4.0
YEAR
2017
C# 7
Tuple

{mostly everything}
static void Main(string[] args)
{
long Factorial(int x)
{
long Aux((int acc, int n) a)
{
if (a.n <= 1) return a.acc;
var r = (a.acc * a.n, a.n - 1);
return Aux(r);
}
(int, int) t = (1, x);
return Aux(t);
}
Console.WriteLine($"1! = {Factorial(1)}");
Console.WriteLine($"3! = {Factorial(3)}");
Console.WriteLine($"20! = {Factorial(20)}");
}
C# 7
Timeline
• Local Functions
• Tuples
• Pattern Matching
Pattern Matching
type 1
type 2
other
type 2 Matcher
YEAR
2010
C# 4.0
Pattern Matching

{types}
static void Main(string[] args)
{
var values = new List<object>
{1, (short) 2,
(Int32) 3, null,
new {}, "no", 1.2d};
foreach (var value in values)
{
var x = value as int;
if (x != null)
Console.WriteLine("got “ + x);
}
}
C# 4.0
YEAR
2017
C# 7
Pattern Matching

{types}
static void Main(string[] args)
{
var values = new List<object>
{1, (short) 2,
(Int32) 3, null,
new {}, "no", 1.2d};
foreach (var value in values)
{
if (value is int x)
Console.WriteLine($"got {x}");
}
}
C# 7
Function

Pattern

Matching
YEAR
1973
ML
Pattern Matching

{functional pattern matching}
fun factorial(0) = 1
| factorial(n) = n * factorial(n-1);
print(
"5! =" ^ (Int.toString (factorial(5))) ^ "n");
ML
YEAR
2004
Scala
Pattern Matching

{functional pattern matching}
import scala.annotation.tailrec
object factorial {
def apply(x: Int): Int = {
@tailrec
def go(m: Int, x: Int): Int = x match {
case 0 => m
case _ => go(x*m, x-1)
}
go(1, x)
}
}
println(s"5! = ${factorial(5)}")
Scala
YEAR
2018
C# 8
Pattern Matching

{functional pattern matching}
long Factorial(int x)
{
long Aux(int m, int x)
{
match(x)
{
case 0: return m;
default: return Aux(x*m, x-1);
}
}
return Aux(1, x);
}
Console.WriteLine($"5! = {Factorial(5)}");
C# 8
YEAR
2018
C# 8
Pattern Matching

{types}
static void Main(string[] args)
{
var values = new List<object>
{1, (short) 2,
(Int32) 3, null,
new {}, "no", 1.2d};
foreach (var value in values)
{
t = match(x)
{
case int _: "int";
case short _: "short";
case object _: "object";
case string _: "string";
default: "something";
}
Console.WriteLine("got “ + t);
}
}
C# 8
Pattern Matching

{types}
foreach (var value in values)
{
t = match(x)
{
case int _: "int";
case short _: "short";
case object _: "object";
case string _: "string";
default: "something";
}
Console.WriteLine("got “ + t);
}
C# 8
Thank you!
Mike Harris



@MikeMKH

http://comp-phil.blogspot.com/
Biography
• Tomas Petricek - "Coeffects: Context-aware programming
languages" http://tomasp.net/coeffects/
• https://github.com/dotnet/roslyn/blob/features/patterns/
docs/features/local-functions.md
• https://github.com/dotnet/roslyn/issues/347
• https://github.com/dotnet/roslyn/blob/features/patterns/
docs/features/patterns.md
• https://github.com/dotnet/roslyn/blob/master/docs/
Language%20Feature%20Status.md
Images
• DeLorean DMC-12 by en:user:Grenex - Wikipedia en, CC BY-SA 3.0,
https://commons.wikimedia.org/w/index.php?curid=2500249
• Herodotos by © Marie-Lan Nguyen / Wikimedia Commons, Public
Domain, https://commons.wikimedia.org/w/index.php?curid=12886457
• Lysander by Walter Crane - The story of Greece : told to boys and girls
(191-?) by Macgregor, Mary, Public Domain, https://
commons.wikimedia.org/w/index.php?curid=32804563
• Socrates by Walter Crane - The story of Greece : told to boys and girls
(191-?) by Macgregor, Mary, Public Domain, https://
commons.wikimedia.org/w/index.php?curid=32804549
• Hegel by Unknown - http://portrait.kaar.at/, Public Domain, https://
commons.wikimedia.org/w/index.php?curid=3308762

C# 7

  • 3.
  • 5.
  • 8.
  • 9.
    “Herodotus of Halicarnassus here presentshis research so that human events do not fade with time.” Herodotus, The Histories
 Book I, Proem
 trans. Andrea L. Purvis

  • 11.
  • 12.
    “[Sparta] they wouldnever reduce to slavery a city which was itself an integral portion of Hellas, and had performed a great and noble service to Hellas in the most perilous of emergencies.” Xenophon, Hellenica
 Book 2, 2.20
 trans. H. G. Dakyns

  • 14.
  • 15.
    “[Writing offers readers]the appearance of wisdom, not true wisdom, for they will read many things without instruction and will therefore seem to know many things, when they are for the most part ignorant and hard to get along with, since they are not wise, but only appear wise.” Plato, Phaedrus 275a-b
 trans. Harold N. Fowler

  • 17.
  • 18.
    “World history is therecord of the spirit's efforts to attain knowledge of what it is in itself.” Hegel, Lectures on the Philosophy of World History
 Introduction
 trans. Johannes Hoffmeister

  • 20.
    Timeline • Local Functions •Tuples • Records • Pattern Matching • Ref Locals / Ref Returns • Binary Literals / Digit Separators
  • 21.
    Timeline • Local Functions •Tuples • Pattern Matching
  • 23.
    Timeline • Local Functions •Tuples • Pattern Matching
  • 25.
  • 26.
    Local Functions
 {Algol 60} begin commentclassic recursive procedure; integer nn, nf; integer procedure factorial(n); value n; integer n; begin if n <= 1 then factorial := 1 else factorial := n * factorial(n-1) end; nn := 5; nf := factorial(nn); outinteger ( 1 , nf) end taken from: http://algol60.org/lego/procedure11.a60Algol 60
  • 27.
    Local Functions
 {Algol 60} integerprocedure factorial(n); value n; integer n; begin if n <= 1 then factorial := 1 else factorial := n * factorial(n-1) end; nn := 5; nf := factorial(nn); taken from: http://algol60.org/lego/procedure11.a60Algol 60
  • 29.
  • 30.
    Local Functions
 {without languagesupport} private struct locals { public int x; } static void Main(string[] args) { var x = 42; var local = new locals {x = x}; AddOne(ref local); x = local.x; WriteLine($"x + 1 = {x}"); } private static void AddOne(ref locals implicits) { implicits.x += 1; } C# 6
  • 32.
  • 33.
    Local Functions
 {with languagesupport} static void Main(string[] args) { var x = 42; void AddOne() { x += 1; } AddOne(); WriteLine($"x + 1 = {x}"); } C# 7
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
    Functions
 {basic} public int Hello(stringname) { var time = DateTime.Now; Console.Write($"Hello {name} it is now {time}"); return name.Length; } C# 6
  • 39.
  • 40.
    Functions
 {real world} public intHello(string name) { var time = DateTime.Now; Console.Write($"Hello {name} it is now {time}"); return name.Length; } C# 6
  • 42.
  • 43.
    Local Functions
 {“realistic”} static voidMain(string[] args) { var program = new Program(); IEnumerable<int> values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; string FormatValues() { return string.Join(",", values); } Console.WriteLine($"before: {FormatValues()}"); values = program.RealistCode(values); Console.WriteLine($"after: {FormatValues()}"); } public IEnumerable<int> RealistCode(IEnumerable<int> values) { if (values == null) throw new ArgumentException("values cannot be null"); if (!values.Any()) throw new ArgumentException("must have at least one element in values"); IEnumerable <int> Rules() { return values .Where(x => x > 2) .Where(x => x%2 == 1); } return Rules(); } C# 7
  • 44.
    Local Functions
 {“realistic”} static voidMain(string[] args) { var program = new Program(); IEnumerable<int> values = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; string FormatValues() { return string.Join(",", values); } Console.WriteLine($"before: {FormatValues()}"); values = program.RealistCode(values); Console.WriteLine($"after: {FormatValues()}"); } C# 7
  • 45.
    Local Functions
 {really “realistic”} publicIEnumerable<int> RealistCode(IEnumerable<int> values) { if (values == null) throw new ArgumentException("values cannot be null"); if (!values.Any()) throw new ArgumentException( "must have at least one element in values"); IEnumerable <int> Rules() { return values .Where(x => x > 2) .Where(x => x%2 == 1); } return Rules(); } C# 7
  • 46.
    Local Functions
 {really “realistic”} publicIEnumerable<int> RealistCode(IEnumerable<int> values) { Precondition(); return values .Where(x => x > 2) .Where(x => x%2 == 1); void Precondition() { if (values == null) throw new ArgumentException("values cannot be null"); if (!values.Any()) throw new ArgumentException("must have at least one element in values"); } } C# 7
  • 47.
  • 48.
  • 49.
    Local Functions
 {design bycontract} note description : "example of factorial" class APPLICATION create make feature -- Initialization make local n: NATURAL do n := 3 print ("%NFactorial of " + n.out + " = ") print (recursive_factorial (n)) end feature -- Access recursive_factorial (n: NATURAL): NATURAL require n >= 0 do if n = 0 then Result := 1 else Result := n * recursive_factorial (n - 1) end end end Eiffel
  • 50.
    Local Functions
 {design bycontract} feature -- Access recursive_factorial (n: NATURAL): NATURAL require n >= 0 do if n = 0 then Result := 1 else Result := n * recursive_factorial (n - 1) end end end Eiffel
  • 52.
  • 53.
    Local Functions
 {design bycontract} (ns com.blogspot.comp-phil.factorial) ;; no tail call optimization (defn factorial [n] {:pre [((comp not neg?) n)]} (if (= n 0) 1 (* n (factorial (dec n))))) (factorial 1) (factorial 5) Clojure
  • 54.
    Local Functions
 {design bycontract} (defn factorial [n] {:pre [((comp not neg?) n)]} (if (= n 0) 1 (* n (factorial (dec n))))) Clojure
  • 56.
  • 57.
    Local Functions
 {design bycontract} static void Main(string[] args) { // no tail call optimization long Factorial(int x) { if (x < 0) throw new ArgumentException(“value < 0”); if (x <= 1) return 1; return x * Factorial(x-1); } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 58.
  • 59.
  • 60.
    Local Functions
 {no tailcall} static void Main(string[] args) { // no tail call optimization long Factorial(int x) { if (x <= 1) return 1; return x * Factorial(x-1); } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 61.
    Console.WriteLine($"3! = {Factorial(3)}"); longFactorial(int x) { if (x <= 1) return x; return x * Factorial(x-1); } x = 3
 3 * ? C# 7
  • 62.
    Console.WriteLine($"3! = {Factorial(3)}"); longFactorial(int x) { if (x <= 1) return x; return x * Factorial(x-1); } x = 3
 3 * x = 2
 2 * ? C# 7
  • 63.
    Console.WriteLine($"3! = {Factorial(3)}"); x= 3
 3 * long Factorial(int x) { if (x <= 1) return x; return x * Factorial(x-1); } x = 2
 2 * x = 1
 1 C# 7
  • 64.
    Console.WriteLine($"3! = {Factorial(3)}"); x= 3
 3 * long Factorial(int x) { if (x <= 1) return x; return x * Factorial(x-1); } x = 2
 2 C# 7
  • 65.
    Console.WriteLine($"3! = {Factorial(3)}"); x= 3
 6 long Factorial(int x) { if (x <= 1) return x; return x * Factorial(x-1); } C# 7
  • 67.
    Local Functions
 {tail call} staticvoid Main(string[] args) { // would have tail call optimization if supported long Factorial(int x) { long Aux(long acc, int n) { if (n <= 1) return acc; return Aux(acc * n, n - 1); } return Aux(1, x); } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 68.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 1
 n = 3 long Aux(long acc, int n) { if (n <= 1) return acc; return Aux(acc * n, n - 1); } C# 7
  • 69.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 1
 n = 3 acc = 3
 n = 2 long Aux(long acc, int n) { if (n <= 1) return acc; return Aux(acc * n, n - 1); } C# 7
  • 70.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 1
 n = 3 acc = 3
 n = 2 acc = 6
 n = 1 long Aux(long acc, int n) { if (n <= 1) return acc; return Aux(acc * n, n - 1); } C# 7
  • 72.
    Local Functions
 {“tail calloptimization”} static void Main(string[] args) { // simulated tail call optimization long Factorial(int n) { long acc = 1; top: if (n <= 1) return acc; acc *= n; n--; goto top; } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 73.
    Local Functions
 {“tail calloptimization”} static void Main(string[] args) { // simulated tail call optimization long Factorial(int n) { long acc = 1; top: if (n <= 1) return acc; acc *= n; n--; goto top; } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 74.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 1
 n = 3 long Factorial(int n) { long acc = 1; top: if (n <= 1) return acc; acc *= n; n--; goto top; }C# 7
  • 75.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 3
 n = 2 long Factorial(int n) { long acc = 1; top: if (n <= 1) return acc; acc *= n; n--; goto top; }C# 7
  • 76.
    Console.WriteLine($"3! = {Factorial(3)}"); acc= 6
 n = 1 long Factorial(int n) { long acc = 1; top: if (n <= 1) return acc; acc *= n; n--; goto top; }C# 7
  • 78.
  • 79.
    Local Functions
 {tail calloptimization} F# module Factorial = let factorial x = let rec aux m x = match x with | 0 -> m | _ -> aux (m*x) (x-1) aux 1 x
  • 81.
    Timeline • Local Functions •Tuples • Pattern Matching
  • 82.
  • 83.
  • 85.
  • 86.
    Tuple
 {mostly everything} static voidMain(string[] args) { Console.WriteLine("1! = “ + Factorial(1)); Console.WriteLine("5! = “ + Factorial(5)); Console.WriteLine("20! = “ + Factorial(20)); } private static long Factorial(int x) { return FactorialAux(new Tuple<int, int>(1, x)); } private static long FactorialAux(Tuple<int, int> t) { if (t.Item2 <= 1) return t.Item1; var r = new Tuple<int, int>(t.Item1*t.Item2, t.Item2 - 1); return FactorialAux(r); } C# 4.0
  • 88.
  • 89.
    Tuple
 {mostly everything} static voidMain(string[] args) { long Factorial(int x) { long Aux((int acc, int n) a) { if (a.n <= 1) return a.acc; var r = (a.acc * a.n, a.n - 1); return Aux(r); } (int, int) t = (1, x); return Aux(t); } Console.WriteLine($"1! = {Factorial(1)}"); Console.WriteLine($"3! = {Factorial(3)}"); Console.WriteLine($"20! = {Factorial(20)}"); } C# 7
  • 91.
    Timeline • Local Functions •Tuples • Pattern Matching
  • 92.
    Pattern Matching type 1 type2 other type 2 Matcher
  • 94.
  • 95.
    Pattern Matching
 {types} static voidMain(string[] args) { var values = new List<object> {1, (short) 2, (Int32) 3, null, new {}, "no", 1.2d}; foreach (var value in values) { var x = value as int; if (x != null) Console.WriteLine("got “ + x); } } C# 4.0
  • 97.
  • 98.
    Pattern Matching
 {types} static voidMain(string[] args) { var values = new List<object> {1, (short) 2, (Int32) 3, null, new {}, "no", 1.2d}; foreach (var value in values) { if (value is int x) Console.WriteLine($"got {x}"); } } C# 7
  • 99.
  • 100.
  • 101.
    Pattern Matching
 {functional patternmatching} fun factorial(0) = 1 | factorial(n) = n * factorial(n-1); print( "5! =" ^ (Int.toString (factorial(5))) ^ "n"); ML
  • 103.
  • 104.
    Pattern Matching
 {functional patternmatching} import scala.annotation.tailrec object factorial { def apply(x: Int): Int = { @tailrec def go(m: Int, x: Int): Int = x match { case 0 => m case _ => go(x*m, x-1) } go(1, x) } } println(s"5! = ${factorial(5)}") Scala
  • 106.
  • 107.
    Pattern Matching
 {functional patternmatching} long Factorial(int x) { long Aux(int m, int x) { match(x) { case 0: return m; default: return Aux(x*m, x-1); } } return Aux(1, x); } Console.WriteLine($"5! = {Factorial(5)}"); C# 8
  • 109.
  • 110.
    Pattern Matching
 {types} static voidMain(string[] args) { var values = new List<object> {1, (short) 2, (Int32) 3, null, new {}, "no", 1.2d}; foreach (var value in values) { t = match(x) { case int _: "int"; case short _: "short"; case object _: "object"; case string _: "string"; default: "something"; } Console.WriteLine("got “ + t); } } C# 8
  • 111.
    Pattern Matching
 {types} foreach (varvalue in values) { t = match(x) { case int _: "int"; case short _: "short"; case object _: "object"; case string _: "string"; default: "something"; } Console.WriteLine("got “ + t); } C# 8
  • 113.
  • 115.
    Biography • Tomas Petricek- "Coeffects: Context-aware programming languages" http://tomasp.net/coeffects/ • https://github.com/dotnet/roslyn/blob/features/patterns/ docs/features/local-functions.md • https://github.com/dotnet/roslyn/issues/347 • https://github.com/dotnet/roslyn/blob/features/patterns/ docs/features/patterns.md • https://github.com/dotnet/roslyn/blob/master/docs/ Language%20Feature%20Status.md
  • 116.
    Images • DeLorean DMC-12by en:user:Grenex - Wikipedia en, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=2500249 • Herodotos by © Marie-Lan Nguyen / Wikimedia Commons, Public Domain, https://commons.wikimedia.org/w/index.php?curid=12886457 • Lysander by Walter Crane - The story of Greece : told to boys and girls (191-?) by Macgregor, Mary, Public Domain, https:// commons.wikimedia.org/w/index.php?curid=32804563 • Socrates by Walter Crane - The story of Greece : told to boys and girls (191-?) by Macgregor, Mary, Public Domain, https:// commons.wikimedia.org/w/index.php?curid=32804549 • Hegel by Unknown - http://portrait.kaar.at/, Public Domain, https:// commons.wikimedia.org/w/index.php?curid=3308762