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
Sobolev Nikita
September 23, 2017
Programming
110
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Elixir is not Ruby, it is better
Sobolev Nikita
September 23, 2017
More Decks by Sobolev Nikita
See All by Sobolev Nikita
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
240
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
210
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
130
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
130
Дотянуться до кремния. HighLoad Python: SIMD, GPU – Пётр Андреев, PythoNN
sobolevn
0
120
Проектирование — это когда чувствуешь, а не какие-то там циферки, Николай Хитров, PythoNN
sobolevn
0
140
Continuous profiling, Давид Джалаев, PythoNN
sobolevn
0
160
Михаил Гурбанов – Are you NATS? @ PythoNN
sobolevn
0
320
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
sobolevn
0
69
Other Decks in Programming
See All in Programming
今さら聞けない .NET CLI
htkym
0
130
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
660
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
1k
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.3k
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
230
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
430
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.7k
えっ!!コードを読まずに開発を!?
hananouchi
0
240
1年で人数1.5倍、PR数5.5倍増。 品質とアウトカムはどうなったか、 何が効いたか
ike002jp
0
150
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
550
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
8
15k
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.1k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
180
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Paper Plane
katiecoart
PRO
2
52k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
280
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
590
The Limits of Empathy - UXLibs8
cassininazir
1
540
Statistics for Hackers
jakevdp
799
230k
RailsConf 2023
tenderlove
30
1.5k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
360
Tell your own story through comics
letsgokoyo
1
1k
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