25
31.01.2014 Введение в функциональное программирование [email protected] @gliush

fp intro

Embed Size (px)

DESCRIPTION

Введение в функциональное программирование, которое я рассказывал в #mcst

Citation preview

Page 1: fp intro

31.01.2014

Введение в функциональное программирование

[email protected]!@gliush

Page 2: fp intro

Императивное программирование

✤ Последовательность модификаций состояния!

✤ начальное значение S0 (входные значения)!

✤ конечное значение Sn (конечное значение)!

✤ модификация с помощью команд присваивания!

✤ Sn = f(S0)!

✤ абстрагирование от низкоуровневых деталей

Page 3: fp intro

Функциональное программирование

✤ вся программа - одно [матем.] выражение!

✤ выполнение - вычисление значения выражения!

✤ языковые конструкции для облегчения чтения и написания программ!

✤ абстрактная система для записи алгоритма -> перевод на императивный язык низкого уровня

Page 4: fp intro

Отличительные особенности ФП

✤ не используют “переменные”!

✤ нет оператора присваивания!

✤ нет циклов!

✤ функции - обычные значения!

✤ рекурсия!

✤ могут напрямую соответствовать матем. объектам

Page 5: fp intro

Примеры

✤ Всеми любимый пример “факториал”!

✤ Сама функция: foo n = if n == 0 then 1 else n * foo (n-1)!

✤ Матем. описание: f(n): n! n >= 0 ⏊ n < 0

Page 6: fp intro

Функции императивных языков

✤ значение зависит не только от аргументов!

✤ результатом могут быть побочные эффекты!

✤ два вызова могут приводить к разному результату!

✤ вывод: это не функции в математическом смысле

Page 7: fp intro

Лямбда-исчисление (lambda calculus)

✤ создана в начале 30х годов!

✤ формализация для написания программ!

✤ простая модель для рекурсии и вложенных сред!

✤ лямбда выражения (анонимные функции)!

Page 8: fp intro

Введение в лямбда-исчисление: лямбда-терм

✤ Переменные!

✤ Константы!

✤ Комбинации: применение функции S к аргументу T: (S T). И S и T - могут быть произвольными лямбда-термами!

✤ Абстракции произвольного лямбда терма S по переменной x: λ x . S!

✤ Exp = Var | Const | Exp Exp | λ Var . Exp!

✤ Представляется в виде дерева, а не строки. Поэтому любые договоренности написания - не часть формальной системы.

Page 9: fp intro

Введение в лямбда-исчисление: обзор

✤ Свободные и связанные переменные:S = (λ x y . x) (λ x . z x) => FV(S) = {z}, BV(S) = {x,y}!

✤ Подстановкиприменение λx.S к аргументу T дает S[x := T]!

✤ Каррирование (R -> R -> R) = (R -> (R -> R))(λ x y . x + y) 1 2 = (λ y . 1 + y) 2 = 1 + 2 = 3

Page 10: fp intro

Введение в лямбда-исчисление: преобразования

✤ Альфа-преобразование: λ x . S -> λ y . S [x := y], if y ∉ FV(T)!

✤ Бета-преобразование:(λ x .S) T -> S [x := T]!

✤ Эта-преобразование: λ x . T x -> T, if x ∉ FV(T)!

✤ позволяют переходить к эквивалентному терму!

✤ равенство лямбда-термов!

✤ редукция лямбда-термов, в том числе к “нормальной” форме

Page 11: fp intro

Введение в лямбда-исчисление: пример Bool значений и условий

✤ Bool - тип, представляющий функцию от двух переменныхtrue ~> λ x y . x false ~> λ x y . y!

✤ if E then E1 else E2 ~> E E1 E2 Пример:if true then E1 else E2 = true E1 E2 = (λ x y . x) E1 E2 = λ y . E1 = E1!

✤ not p = if p then false else true p and q = if p then q else false p or q = if p then true else q

Page 12: fp intro

Введение в лямбда-исчисление: пример натуральных чисел

✤ Любое натуральное число N - это выполнение функции suc n раз: n = suc (suc (suc … (0)) …)!

✤ Достаточно определитьsuciszeroчтобы поддержатьm + n m * n pre n

Page 13: fp intro

Введение в лямбда-исчисление: типизация

✤ дают ясное представление о функции, если знать область определения и значений!

✤ эффективность (int8, int64) по mem и по cpu!

✤ статическая проверка программ!

✤ модульность и скрытие данных!

✤ позволяют обойти некоторые мат. противоречия

Page 14: fp intro

типизация в ЯП

✤ строгая типизация - мягкая типизацияint a[] = {1,2,3,4.0}; /* c - it’s ok */let a = [1,2,3,4.0] - - haskell - not ok A = [1,2,3,4,”hello”, [“world”]]. % erlang - it’s ok!

✤ динамическая типизация - статическая типизация!

✤ полиморфизм типов!

✤ автоматический вывод типов

Page 15: fp intro

Типизированное лямбда-исчисление

✤ Каждый лямбда-терм имеет тип!

✤ терм S можно применить к терму T, если их типы правильно соотносятся (сильная типизация): S :: a -> b T :: aS T :: b!

✤ Базовые типы: Int, Bool!

✤ Конструктор типов: Int; Bool; Bool -> Bool; [Bool] -> Bool

Page 16: fp intro

Отложенные (ленивые) вычисления

✤ (λ x . x + x + x) (10 + 5):(10 + 5) + (10 + 5) + (10 + 5) - нормальная редукция(15 + 15 + 15) - передача по значению!

✤ Передача по значению обычно более эффективна необходима для гибридных языков!

✤ Вызов по необходимости позволяет исп. ленивые вычисления!

✤ bottom = bottom - - Haskell: никогда не завершитсяconst1 x = 1 - - нет необходимости проверять аргументconst1 bottom -> 1 const1 (1/0) -> 1!

✤ Плата: снижение эффективности при сохранении отложенных вычислений

Page 17: fp intro

Пример ленивых вычислений

✤ ones = 1 : onesnumsFrom n = n : numsFrom (n+1) square x = x^2squres = map square (numsFrom 1)!

✤ take 5 (numsFrom 1) -> [1,2,3,4,5]!

✤ take 5 squares -> [1,4,9,16,25]

Page 18: fp intro

real world функции

✤ как в чисто функциональном языке сделать print?!

✤ сравнение функции random: /* c-like, нет входа, случайный результат */ long random(void); - - haskell: generator as input, new generator as outputrandom :: RandomGen g => g -> (a, g)

Page 19: fp intro

Введение в haskell

✤ статическая типизация: тип объекта фиксируется в момент компиляции!

✤ строгая типизация (imp. статическая типизация): строго определенные типы для любых операцийприсваивание переменной только значения того же типа не допускается неявное преобразование типов!

✤ чистый язык: детерменированность и отсутствие побочных эффектов

Page 20: fp intro

Синтаксис haskell

✤ идентификаторы: someFunction, foo, foo’, abc123. Каждому идентификатору можно сопоставить тип!

✤ Знаки операций, приоритеты между ними: + , - , * , / , ++!

✤ clause функций factorial 0 = 1 factorial n = n * factorial (n-1)!

✤ guardsfactorial n | n == 0 = 1 | otherwise = n * factorial (n - 1)!

✤ indentation!

✤ backquote:div 10 5 -> 2 10 `div` 5 -> 2

Page 21: fp intro

Введение в haskell 2

✤ элементарные типы: Int, Bool, Char, Float!

✤ Конструкторы типов: кортежи (tuples), списки, random :: g -> (a,g)map :: (a->b) -> [a] -> [b]!

✤ алгебраические типы данных (ADT): data Maybe a = Just a | Nothing!

Page 22: fp intro

haskell tools

!

✤ hoogle search!

✤ ghci repl!

✤ ghc compiler extensions

Page 23: fp intro

Недостатки

✤ сложность восприятия!

✤ gc mem!

✤ gc cpu

Page 24: fp intro

списки как пример простоты “ядра языка” haskell

✤ Поддержка - на уровне библиотек.!

✤ Работа со списками[] [1,2,3] 1:[2,3] [1,2] ++ [3](1:(2:(3:([]))))!

✤ map :: (a -> b) -> [a] -> [b]foldl :: (a -> b -> a) -> a -> [b] -> ahead :: [a] -> a tail :: [a] -> [a]length :: [a] -> Int null :: [a] -> Bool!

✤ foldl (+) 0 [1,2,3,4] -> 10 map (^2) [1,2,3,4] -> [1,4,9,16]head [1,2,3,4] -> 1 tail [1,2,3,4] -> [2,3,4]

Page 25: fp intro

Вопросы?

[email protected]!

✤ facebook: gliush!

✤ twitter: @gliush