Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Elixir is not Ruby, it is better
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Sobolev Nikita
September 23, 2017
Programming
0
95
Elixir is not Ruby, it is better
Sobolev Nikita
September 23, 2017
Tweet
Share
More Decks by Sobolev Nikita
See All by Sobolev Nikita
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
200
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
180
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
73
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
68
Дотянуться до кремния. HighLoad Python: SIMD, GPU – Пётр Андреев, PythoNN
sobolevn
0
75
Проектирование — это когда чувствуешь, а не какие-то там циферки, Николай Хитров, PythoNN
sobolevn
0
110
Continuous profiling, Давид Джалаев, PythoNN
sobolevn
0
120
Михаил Гурбанов – Are you NATS? @ PythoNN
sobolevn
0
150
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
sobolevn
0
55
Other Decks in Programming
See All in Programming
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.9k
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
7.4k
LLM Observabilityによる 対話型音声AIアプリケーションの安定運用
gekko0114
2
430
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
230
Smart Handoff/Pickup ガイド - Claude Code セッション管理
yukiigarashi
0
130
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.4k
AIフル活用時代だからこそ学んでおきたい働き方の心得
shinoyu
0
130
AI巻き込み型コードレビューのススメ
nealle
1
180
Patterns of Patterns
denyspoltorak
0
1.4k
【卒業研究】会話ログ分析によるユーザーごとの関心に応じた話題提案手法
momok47
0
200
Featured
See All Featured
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
64
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.6k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.1k
Building Adaptive Systems
keathley
44
2.9k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
160
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
710
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
300
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.7k
Practical Orchestrator
shlominoach
191
11k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
180
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
99
Transcript
Никита Соболев https://github.com/sobolevn
None
О чем я расскажу • О языке Elixir и интересных
концепциях: почему Elixir - не такой как Ruby? • О принципах построения архитектуры приложения • О том, как писать логику приложения
Почему появляются новые языки?
У существующих есть проблемы • Асинхронность ??? • Производительность ??
• Fault-tolerance ?
Elixir - не Ruby, а лучше
Elixir • Функциональный динамический язык • Основан на виртуальной машине
Erlang • Быстрый и надежный • Просто создан для асинхронных операций
Архитектура
iex(1)> example = [1, 2, 3] [1, 2, 3] iex(2)>
List.replace_at(example, 1, 99) [1, 99, 3] iex(3)> example [1, 2, 3] Иммутабельность
• Ничего нельзя "нахачить" • Идеально подходит для асинхронных задач
• Разные параллельные процессы используют свои копии данных
Асинхронность или «притча о легковесных процессах»
Actor Model
None
None
Есть много высоко- уровневых абстракций Task, GenServer, Agent, ...
iex(1)> task = Task.async(fn -> 4 + 4 end) %Task{owner:
#PID<0.84.0>, pid: #PID<0.86.0>, ref: #Reference<>} iex(2)> Task.await(task) 8
None
Отсутствие состояния
https://github.com/petrovich/ petrovich_elixir
def start_link do Agent.start_link(fn -> load_values() end, name: __MODULE__) end
def get(key) do Agent.get(__MODULE__, fn(state) -> Map.get(state, key) end) end def all do Agent.get(__MODULE__, fn(state) -> state end) end
None
Обработка ошибок
None
None
• Такой подход прекрасно ложится на логику процессов • Позволяет
писать бизнес-код, а не городить костыли
Нам не нужны внешние инфраструктурные зависимости
None
• Docker убивает половину плюсов BeamVM • Redis уступает в
скорости ets • Nginx может быть использован, но не обязательно • (G)Unicorn совсем не нужен
Бизнес-логика
Pipes
Enum.count(Enum.uniq([1, 2, 2, 2, 3])) # => 3 [1, 2,
2, 2, 3] |> Enum.uniq() |> Enum.count() # => 3
request |> validate_request() |> fetch_users() |> attach_messages(:sent) |> render_result(:json)
• Код очень легко читать и писать • Низкий порог
входа
• Вызывает привыкание
Паттерн матчинг «Сопоставление с шаблоном»
iex(1)> i = [1, 2, 3] [1, 2, 3] iex(2)>
[one, two, three] = i [1, 2, 3] iex(3)> one 1 iex(4)> three 3
iex(1)> {:ok, result} = {:ok, 15} {:ok, 15} iex(1)> {:ok,
result} = {:error, "Timeout"} ** (MatchError) no match of right hand side value: {:error, "Timeout"}
iex(1)> person = %{"name" => "Nikita", "job" => "developer"} %{"job"
=> "developer", "name" => "Nikita"} iex(2)> %{"name" => name} = person %{"job" => "developer", "name" => "Nikita"} iex(3)> name "Nikita"
defmodule Greetings do def hello(:people), do: "Hello, people!" def hello({name,
surname}) do "Hello, dear #{name} #{surname}" end def hello(_), do: "Hello, stranger" end
• Очень удобно
• Вызывает сильное привыкание
Отсутствует if
None
case Some.fetch_data() do %{"user" => user} -> {:ok, user} %{"error"
=> reason} -> {:error, reason} _ -> {:error, "Unknown"} end
defmodule Increment do def one(a) when is_integer(a) do a +
1 end def one(_) do :error end end
iex(1)> Increment.one(1) 2 iex(2)> Increment.one("Some") :error
• Делает наш код понятнее • Такой код легче тестировать
• Его легче расширять
Нет return
None
• Удобнее тестировать • Легче запомнить, как работает функция
Другой взгляд на полиморфизм
defprotocol Size do @doc "Calculates the size of a data
structure" def size(data) end defimpl Size, for: BitString do def size(string), do: byte_size(string) end defimpl Size, for: Map do def size(map), do: map_size(map) end defimpl Size, for: Tuple do def size(tuple), do: tuple_size(tuple) end
defmodule Parser do @callback parse(String.t) :: any @callback extensions() ::
[String.t] end defmodule JSONParser do @behaviour Parser def parse(str), do: # ... parse JSON def extensions, do: ["json"] end defmodule YAMLParser do @behaviour Parser def parse(str), do: # ... parse YAML def extensions, do: ["yml"] end
• Позволяет переиспользовать код • Позволяет проектировать красивый API
None
https://twitter.com/elixir_lang_mos https://github.com/wunsh/elixir-docs-ru
https://github.com/sobolevn