SlideShare a Scribd company logo
1 of 70
Download to read offline
Интерпретирование языков
с помощью Free-монад
https://twitter.com/ZhekaKozlov
Пример 1: Console I/O
echo ∷ IO ()
echo = do
s ← getLine
putStrLn s
Проблемы
Как убедиться, что echo вызывает
только функции работы с консолью?
Мы не можем «заглянуть внутрь» IO и
проконтролировать, что не
происходят нежелательные
эффекты!
Нежелательный эффект
echo ∷ IO ()
echo = do
s ← getLine
launchMissile
putStrLn s
launchMissile ∷ IO ()
launchMissile = …
Калькулятор
calculator ∷ IO ()
calculator = do
x ← getLine
y ← getLine
putStrLn (show (read x + read y))
Проблемы
Как протестировать calculator?
сalculator возвращает IO() – мы не
можем протестировать ()!
Легко допустить ошибку
calculator ∷ IO ()
calculator = do
x ← getLine
y ← getLine
putStrLn (show (read x + read x))
Решение?
В этой книге!
1994 год
1994 год
RIP
Шаблон Интепретатор
«… определяет грамматику простого
языка, представляет предложения на
этом языке и интерпретирует их»
Пример грамматики
expression ← literal | alternation |
sequence | repetition | '(' expression ')'
alternation ← expression '|' expression
sequence ← expression '&' expression
repetition ← expression '*'
literal ← ['a'..'z']*
Диаграмма классов
RegularExpression
interpret()
LiteralExpression
interpret()
literal
SequenceExpression
interpret()
expression1
expression2
RepetitionExpression
interpret()
expression
AlternateExpression
interpret()
expression1
expression2
Диаграмма классов
Expr
interpret()
Literal
interpret()
literal
And
interpret()
expression1
expression2
Many
interpret()
expression
Or
interpret()
expression1
expression2
ADT!
data Expr =
Literal String |
And Expr Expr |
Or Expr Expr |
Many Expr
Интерпретатор
interpret ∷ String → Expr → (Bool, String)
interpret s (Literal lit)
| lit `isPrefixOf` s =
(True, drop (length lit) s)
interpret s (And e1 e2)
| (True, tail) ← interpret s e1 =
interpret tail e2
interpret s (Or e1 e2)
| (ok, tail) ← interpret s e1 =
if ok then (True, tail) else interpret s e2
interpret s (Many e)
| (ok, tail) ← interpret s e =
if ok then interpret tail (Many e) else (True, s)
interpret s _ = (False, s)
raining & (dogs | cats)*
And
expression1
expression2
Literal
‘raining’
Or
expression1
expression2
Many
expression
Literal
‘dogs’
Literal
‘cats’
raining & (dogs | cats)*
ex = And (Literal "raining")
(Many (Or (Literal "dogs")
(Literal "cats")))
raining & (dogs | cats)*
ex = And (Literal "raining")
(Many (Or (Literal "dogs")
(Literal "cats")))
> interpret "rainingdogscats1" ex
(True,"1")
> interpret "abc" ex
(False,"abc")
Таким образом
• Шаблон Интерпретатор определяет грамматику:
data Expr = Literal String |
And Expr Expr |
Or Expr Expr |
Many Expr
And (Literal "raining")
(Many (Or (Literal "dogs")
(Literal "cats")))
• … представляет предложения на этом языке:
• … и интерпретирует их:
interpret = …
Console I/O
Можно ли применить шаблон
Интерпретатор для языка консольного
ввода-вывода?
Console I/O
Можно ли применить шаблон
Интерпретатор для языка консольного
ввода-вывода?
Можно
Диаграмма классов ADT
Command
PrintLine
String
ReadLine
data Command =
PrintLine String |
ReadLine
Диаграмма классов ADT
Command
PrintLine
String
Command
ReadLine
data Command =
PrintLine String Command |
ReadLine (String → Command)
String → Command
Диаграмма классов ADT
Command a
PrintLine
String
a
ReadLine
data Command a =
PrintLine String a |
ReadLine (String → a)
String → a
echo
data Command a =
PrintLine String a |
ReadLine (String → a)
echo = ReadLine (s → PrintLine s ())
calculator
data Command a =
PrintLine String a |
ReadLine (String → a)
calculator =
ReadLine (x →
ReadLine (y →
PrintLine
(show (read x + read y)) ()))
Проблема
> :type echo
echo ∷ Command (Command ())
> :type calculator
calculator ∷ Command (Command (Command ()))
Проблема
> :type echo
echo ∷ Command (Command ())
> :type calculator
calculator ∷ Command (Command (Command ()))
Как написать интерпретатор для
Command (Command (Command (…)))?
Free
data Free f a =
Return a |
Free (f (Free f a))
echo
data Free f a =
Return a |
Free (f (Free f a))
echo =
Free (ReadLine (s →
Free (PrintLine s (Return ()))))
calculator
data Free f a =
Return a |
Free (f (Free f a))
calculator =
Free (ReadLine (x ->
Free (ReadLine (y ->
Free (PrintLine
(show (read x + read y))
(Return ()))))))
Типы
> :type echo
echo ∷ Free Command ()
> :type calculator
calculator ∷ Free Command ()
Громоздко
calculator =
Free (ReadLine (x ->
Free (ReadLine (y ->
Free (PrintLine
(show (read x + read y))
(Return ()))))))
Free f является монадой!
Утверждение: если f является функтором, то
Free f является монадой.
data Free f a = Return a |
Free (f (Free f a))
Free f является монадой!
Утверждение: если f является функтором, то
Free f является монадой.
data Free f a = Return a |
Free (f (Free f a))
instance Functor f ⇒ Monad (Free f) where
return = Return
(Return a) >>= g = g a
(Free f) >>= g = Free (fmap (>>= g) f)
Command является функтором
data Command a = PrintLine String a |
ReadLine (String → a)
deriving Functor
Command является функтором
data Command a = PrintLine String a |
ReadLine (String → a)
deriving Functor
type Console = Free Command
Command является функтором
data Command a = PrintLine String a |
ReadLine (String → a)
deriving Functor
type Console = Free Command
printLine ∷ String → Console ()
printLine s = Free (PrintLine s (Return ()))
readLine ∷ Console String
readLine = Free (ReadLine (s → Return s))
echo
echo ∷ Console ()
echo = do
s ← readLine
printLine s
echo
echo ∷ Console ()
echo = do
s ← readLine
launchMissile
printLine s
Couldn't match type `IO' with `Console'
calculator
calculator ∷ Console ()
calculator = do
x ← readLine
y ← readLine
printLine (show (read x + read y))
Пишем интерпретатор
runConsole ∷ Console a → IO a
runConsole (Return a) = return a
runConsole (Free command) =
case command of
PrintLine s a → do
putStrLn s
runConsole a
ReadLine after → do
s ← getLine
runConsole (after s)
Запускаем интерпретатор
> runConsole echo
Hello
Hello
> runConsole calculator
3
4
7
2-й интерпретатор (для теста)
Console a
runConsole testConsole
Тест
testConsole ∷
Console a → [String] → [String]
testConsole (Return _) _ = []
testConsole (Free command) inputs =
case command of
PrintLine s a →
s : testConsole a inputs
ReadLine after →
testConsole (after (head
inputs)) (tail inputs)
Запускаем тест
> :m + Test.QuickCheck
> quickCheck (s → testConsole echo
[s] == [s])
+++ OK, passed 100 tests
Запускаем тест
> quickCheck (x y → testConsole
calculator [show x, show y] == [show
(x + y)])
+++ OK, passed 100 tests
3-й интерпретатор (вывод в файл)
Console a
runConsole testConsole
runConsoleFile
Таким образом
• Шаблон Интепретатор определяет грамматику:
data Command a = PrintLine String a |
ReadLine (String → a)
deriving Functor
do s ← readLine
printLine s
• … представляет предложения на этом языке:
• … и интерпретирует их:
runConsole = …
testConsole = …
Пример 2: Key-Value Store
data KVSCommand a =
Put String String a |
Get String (String → a) |
Delete String a
deriving Functor
type KVS = Free KVSCommand
Пример 2: Key-Value Store
put ∷ String → String → KVS ()
put k v = Free (Put k v (Return ()))
get ∷ String → KVS String
get k = Free (Get k Return)
del ∷ String → KVS ()
del k = Free (Delete k (Return ()))
Пример 2: Key-Value Store
put ∷ String → String → KVS ()
put k v = Free (Put k v (Return ()))
get ∷ String → KVS String
get k = Free (Get k Return)
del ∷ String → KVS ()
del k = Free (Delete k (Return ()))
modify ∷ String → (String → String) → KVS ()
modify k f = do v ← get k
put k (f v)
Интерпретатор KVS (NoSQL)
runNoSQL ∷ KVS a → Connection → IO a
runNoSQL = …
Интерпретатор KVS (NoSQL)
runNoSQL ∷ KVS a → Connection → IO a
runNoSQL = …
kvs ∷ KVS String
kvs = do put "firstName" "John"
put "lastName" "Doe"
modify "age" (show.(+1).read)
get "salary"
main = do conn ← getConnection
runNoSQL kvs conn
Интерпретатор KVS (Map)
import Data.Map
runMap ∷ KVS a → Map String String →
Map String String
runMap (Return _) map = map
runMap (Free f) map = case f of
Put k v a → runMap a (insert k v map)
Get k after → runMap (after (map ! k)) map
Delete k a → runMap a (delete k map)
Эффективный интерпретатор
do put "key1" "value1"
put "key2" "value2"
put "key3" "value3"
"key1" ,"value1"
"key2" ,"value2"
"key3" ,"value3"
Эффективный интерпретатор
do put "key1" "value1"
put "key2" "value2"
put "key3" "value3"
"key1" ,"value1"
"key2" ,"value2"
"key3" ,"value3"
["key1" ,"value1",
"key2" ,"value2",
"key3" ,"value3"]
Пример 3: загрузка твитов
import Data.ByteString
data Tweet = Tweet {
id ∷ Integer,
userName ∷ String,
text ∷ String } deriving Show
data User = User {
name ∷ String,
photo ∷ ByteString } deriving Show
fetchTweets ∷ String → Int → IO [Tweet]
fetchUser ∷ String → IO User
Twitter API
fetchTweets ∷ String → Int → IO [Tweet]
fetchTweets "odersky" _ = do
print ("Fetching tweets for @odersky")
return [Tweet 1 "odersky" "Scala!",
Tweet 2 "bos31337" "Haskell!",
Tweet 3 "odersky" "Good morning"]
fetchUser ∷ String → IO User
fetchUser name = do
print ("Fetching user profile for @" ++ name)
return $ case name of
"odersky" → User "odersky" (pack [1,2,3])
"bos31337" → User "bos31337" (pack [4,5])
Хотим достать твиты с фото
fetchTweetsWithPhotos ∷ String → Int →
IO [(Tweet, ByteString)]
fetchTweetsWithPhotos name limit = do
tweets ← fetchTweets name limit
forM tweets (t → do
user ← fetchUser (userName t)
return (t, image user))
Хотим достать твиты с фото
fetchTweetsWithPhotos ∷ String → Int →
IO [(Tweet, ByteString)]
fetchTweetsWithPhotos name limit = do
tweets ← fetchTweets name limit
forM tweets (t → do
user ← fetchUser (userName t)
return (t, image user))
> fetchTweetsWithPhotos "odersky" 10
"Fetching tweets for odersky"
"Fetching user profile for odersky"
"Fetching user profile for bos31337"
"Fetching user profile for odersky"
Хотим достать твиты с фото
fetchTweetsWithPhotos ∷ String → Int →
IO [(Tweet, ByteString)]
fetchTweetsWithPhotos name limit = do
tweets ← fetchTweets name limit
forM tweets (t → do
user ← fetchUser (userName t)
return (t, image user))
> fetchTweetsWithPhotos "odersky" 10
"Fetching tweets for odersky"
"Fetching user profile for odersky"
"Fetching user profile for bos31337"
"Fetching user profile for odersky"
2 запроса!
Решение
data TwitterCommand a =
GetTweets String Int ([Tweet] → a) |
GetUser String (User → a)
deriving Functor
type Twitter = Free TwitterCommand
Решение
data TwitterCommand a =
GetTweets String Int ([Tweet] → a) |
GetUser String (User → a)
deriving Functor
type Twitter = Free TwitterCommand
getTweets ∷ String → Int → Twitter [Tweet]
getTweets name limit =
Free (GetTweets name limit Return)
getUser ∷ String → Twitter User
getUser name = Free (GetUser name Return)
Кэширующий интерпретатор
runTwitter ∷ Twitter a → Map String User → IO a
runTwitter (Return a) _ = return a
runTwitter (Free f) cache = case f of
GetTweets s limit after → do
tweets ← fetchTweets s limit
runTwitter (after tweets) cache
GetUser name after → do
user ← if member name cache
then return (cache ! name)
else fetchUser name
runTwitter (after user)
(insert name user cache)
Кэш фото
Хотим достать твиты с фото
getTweetsWithPhotos ∷ String → Int →
Twitter [(Tweet, ByteString)]
getTweetsWithPhotos name limit = do
tweets ← getTweets name limit
forM tweets (t → do
user ← getUser (userName t)
return (t, photo user))
> runTwitter (getTweetsWithPhotos "odersky" 10)
empty
"Fetching tweets for odersky"
"Fetching user profile for odersky"
"Fetching user profile for bos31337"
1 запрос
Ещё
При желании можно написать интерпретатор,
который распараллеливает запросы.
Существующие библиотеки
Haskell:
• https://github.com/facebook/Haxl
• http://hackage.haskell.org/package/CouchDB
Scala:
• Twitter Stitch (Scala, not open sourced)
• https://github.com/MonsantoCo/stoop
Вопросы?

More Related Content

What's hot

«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНСit-people
 
Kotlin для Android
Kotlin для AndroidKotlin для Android
Kotlin для AndroidKirill Rozov
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотекPyNSK
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьMikhail Kurnosov
 
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Platonov Sergey
 
Why Every Language Needs Its Underscore
Why Every Language Needs Its UnderscoreWhy Every Language Needs Its Underscore
Why Every Language Needs Its UnderscoreAlexander Schepanovski
 
Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовMikhail Kurnosov
 
Лекция 4. Стеки и очереди
Лекция 4. Стеки и очередиЛекция 4. Стеки и очереди
Лекция 4. Стеки и очередиMikhail Kurnosov
 
Лекция 4: Стеки и очереди
Лекция 4: Стеки и очередиЛекция 4: Стеки и очереди
Лекция 4: Стеки и очередиMikhail Kurnosov
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателейDEVTYPE
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаMikhail Kurnosov
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)Smolensk Computer Science Club
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskellhusniyarova
 

What's hot (20)

«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
 
Kotlin для Android
Kotlin для AndroidKotlin для Android
Kotlin для Android
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотек
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. Очередь
 
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
 
Why Every Language Needs Its Underscore
Why Every Language Needs Its UnderscoreWhy Every Language Needs Its Underscore
Why Every Language Needs Its Underscore
 
Java8. Innovations
Java8. InnovationsJava8. Innovations
Java8. Innovations
 
Java 8. Lambdas
Java 8. LambdasJava 8. Lambdas
Java 8. Lambdas
 
Основы SciPy
Основы SciPyОсновы SciPy
Основы SciPy
 
South migration
South migrationSouth migration
South migration
 
Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.Урок 7. Интерпретация и компиляция функциональных программ.
Урок 7. Интерпретация и компиляция функциональных программ.
 
Лекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмовЛекция 11. Методы разработки алгоритмов
Лекция 11. Методы разработки алгоритмов
 
Лекция 4. Стеки и очереди
Лекция 4. Стеки и очередиЛекция 4. Стеки и очереди
Лекция 4. Стеки и очереди
 
Лекция 4: Стеки и очереди
Лекция 4: Стеки и очередиЛекция 4: Стеки и очереди
Лекция 4: Стеки и очереди
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателей
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
 
Scala on android
Scala on androidScala on android
Scala on android
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
 

Similar to Интерпретирование языков с помощью Free-монад

Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliaminComputer Science Club
 
Elixir: The Future of Web Development | Elixir: Будущее веб-разработки
Elixir: The Future of Web Development | Elixir: Будущее веб-разработкиElixir: The Future of Web Development | Elixir: Будущее веб-разработки
Elixir: The Future of Web Development | Elixir: Будущее веб-разработкиYaroslav Smirnov
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Fwdays
 
20100425 model based_testing_kuliamin_lectures01-03
20100425 model based_testing_kuliamin_lectures01-0320100425 model based_testing_kuliamin_lectures01-03
20100425 model based_testing_kuliamin_lectures01-03Computer Science Club
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
Введение в Clojure (Никита Прокопов)
Введение в Clojure (Никита Прокопов)Введение в Clojure (Никита Прокопов)
Введение в Clojure (Никита Прокопов)mainstreamless
 
Ввод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииВвод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииLungu
 
Ввод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииВвод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииLungu
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 

Similar to Интерпретирование языков с помощью Free-монад (20)

Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Discovering Lambdas (Speech)
Discovering Lambdas (Speech)Discovering Lambdas (Speech)
Discovering Lambdas (Speech)
 
20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin
 
Elixir: The Future of Web Development | Elixir: Будущее веб-разработки
Elixir: The Future of Web Development | Elixir: Будущее веб-разработкиElixir: The Future of Web Development | Elixir: Будущее веб-разработки
Elixir: The Future of Web Development | Elixir: Будущее веб-разработки
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Урок 8. Введение в редукцию графов
Урок 8. Введение в редукцию графовУрок 8. Введение в редукцию графов
Урок 8. Введение в редукцию графов
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
 
Coroutines
CoroutinesCoroutines
Coroutines
 
20100425 model based_testing_kuliamin_lectures01-03
20100425 model based_testing_kuliamin_lectures01-0320100425 model based_testing_kuliamin_lectures01-03
20100425 model based_testing_kuliamin_lectures01-03
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
Введение в Clojure (Никита Прокопов)
Введение в Clojure (Никита Прокопов)Введение в Clojure (Никита Прокопов)
Введение в Clojure (Никита Прокопов)
 
Ввод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииВвод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информации
 
Ввод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информацииВвод - вывод алфавитно цифровой информации
Ввод - вывод алфавитно цифровой информации
 
C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
C# Deep Dive
C# Deep DiveC# Deep Dive
C# Deep Dive
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 

More from Zheka Kozlov

Модули в Java
Модули в JavaМодули в Java
Модули в JavaZheka Kozlov
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиZheka Kozlov
 
Java 9 модули
Java 9 модулиJava 9 модули
Java 9 модулиZheka Kozlov
 
Введение в Scalaz
Введение в ScalazВведение в Scalaz
Введение в ScalazZheka Kozlov
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в AkkaZheka Kozlov
 
Сервис MobiBarC
Сервис MobiBarCСервис MobiBarC
Сервис MobiBarCZheka Kozlov
 
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13Zheka Kozlov
 

More from Zheka Kozlov (8)

Модули в Java
Модули в JavaМодули в Java
Модули в Java
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не знали
 
Java 9 модули
Java 9 модулиJava 9 модули
Java 9 модули
 
Введение в Scalaz
Введение в ScalazВведение в Scalaz
Введение в Scalaz
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
 
Xtend
XtendXtend
Xtend
 
Сервис MobiBarC
Сервис MobiBarCСервис MobiBarC
Сервис MobiBarC
 
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
Устойчивый к искажениям алгоритм распознавания штрих-кода EAN-13
 

Интерпретирование языков с помощью Free-монад