Pull to refresh

Pony — убийца...?

Reading time5 min
Views31K
Всем известны такие прогрессивные новички в программировании как — «Go, Rust, Nim, Crystal» и все они очень круты в своих определенных областях.

К примеру:

  1. Go был рожден как супер простой и промышленный язык для быстрого решения поставленных задач с идеями, которые всем прекрасны известны, но некоторые из них прибиты к другим языкам гвоздями (На 5мм).
  2. Второй наш оппонент — это Rust, победитель по жизни, но из-за своей сложной жизни в развитии он стал для сообщества, как будущая и модная замена C++. Для меня его судьба пока не понятна, так как с зелеными потоками и IO под них там пока туго, то я его ставлю на место в ряд с C для микроконтроллеров, драйверов и операционных систем.
  3. Crystal… Прямо и четко говорю, что это супер производительный клон Ruby. Больше сказать нечего, весь он пропитан его духом.
  4. Nim (Он же Нимушка или Нимрод) и его похожесть на скриптовые языки создают ему особую атмосферу, однако внутри он достаточно сложный организм и для меня сия сущность, как Haxe с такими же ощущениями при программировании на нем.

А Pony — это моя любимая и маленькая поняшка. С виду и по названию языка можно лихо пройти мимо… В общем, приглашаю вас под капот статьи.

Это только начало


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

  • Я — Nyarum, известен, как простой пользователь языка Go. Часто задвигаю иронию с Растом и являюсь соавтором Slack сообщества гоферов.
  • Мои петпрожекты всегда связаны с эмулированием онлайн игр. От реверса до воспроизведения серверной части.
  • И я очень люблю Аниме.

Теперь вы знаете все мои секреты, можно и продолжить нашу интересную историю в мир прекрасного Pony.

Язык и краткий ликбез


image
Это тот самый жизнерадостный кормилец и он больше похож на кролика

Pony — объектно-ориентированный язык программирования, построенный в первую очередь на модели акторов и прозрачной конкурентности. В его дополнительных плюсах трутся такие понятия, как — «Open-source, производительность, интересные идеи». Основной упор идет на многоядерный системы, современную разработку без мыслей о низком уровне и очень производительную конкурентность.

Возможности

  • Типобезопасность. Подтвержденная математическим бекграундом.
  • Безопасная работа с памятью. Хоть это и является следствием из типобезопасности, но нельзя упускать данный пункт. В нем вы не найдете повисших указателей, переполнение буффера или в самом частом случае — вам не придется знать, что такое null.
  • Безопасная работа с экзепшенами. Все они определяются на семантическом уровне и никаких рантайм неожиданностей.
  • Скажем нет гонкам данных! Никаких атомиков, мьютексов или таймеров. Система типов с проверками во время компиляции дают высокую гарантию сего понятия. Пишите конкурентный код и не переживайте за остальное.
  • Никаких дедлоков. Следствие из отсутствия любых операций с блокировками.

Краткая спецификация по языку

Система типов:

  • Класс, стандартен из ООП мира. Поля, конструкторы и функции в вашем распоряжении.
    class Habra
      let _name: String
    
      new create(name': String) =>
        _name = name'
    
      fun name(): String => _name
    

  • Актор, идентичен классу, но имеет возможности определения асинхронных функций. Это относится к прозрачной конкурентности.
    actor Habro
      let name: String
      var _hunger_level: U64 = 0
    
      new create(name': String) =>
        name = name'
    
      be eat(amount: U64) =>
        _hunger_level = _hunger_level - amount.min(_hunger_level)
    

  • Примитив, тоже идентичен классу с 2-я различиями. Он не может иметь полей и в процессе работы программы создается только 1 инстанс на определенный вами примитив. Используется для многих вещей, но чаще, как особый вид дженерика с возможностью в None тип, чтобы проверять приходящие из FFI мира значения, не равняется ли оно пустоте.
    primitive _Habras
    

  • Трейт и интерфейс (Являются подтипами, однако определяются так же, как и класс). Многие ЯП имеют только 1 из них одновременно, но в Пони они задействованы оба. Различие в том, что трейт является условной проверкой принадлежности, а интерфейс проверяет соответствие структурно.
    // Trait
    trait Family
      fun age(): U64 => 5
    
    class Habravi is Family
    
    // Interface
    interface Habrovik
      fun name(): String
    
    class Habrovichek
      fun name(): String => "Model #1"
    

  • Алиасы для типов. Не буду говорить тут про них много, мощная система и требует самостоятельного изучения.
    // Enumeration
    primitive Red
    primitive Blue
    primitive Green
    
    type Colour is (Red | Blue | Green)
    
    // Complex
    interface HasName
      fun name(): String
    
    interface HasAge
      fun age(): U32
    
    interface HasAddress
      fun address(): String
    
    type Person is (HasName & HasAge & HasAddress)
    

  • Кортеж есть последовательность типов, которые могут быть определены в одной переменной.
    var x: (String, U64)
    x = ("hi", 3)
    

  • Юнион очень похож на кортеж, только используется для обобщения возможных типов. Особый вид дженерика.
    var x: (String | U64)
    x = "hello habr"
    
    // or
    
    x = 5
    

  • Пересечение почти является противоположностью юниона и может описывать одно значение для нескольких типов одновременно. В примере ниже видно, как карта может содержать одновременно ключ двух разных типов.
    type Map[K: (Hashable box & Comparable[K] box), V] is HashMap[K, V, HashEq[K]]
    

  • Все выше описанные выражения типов могут комбинироваться
    // Tuple in Union which in Array
    var _array: Array[((K, V) | _MapEmpty | _MapDeleted)]
    



Стандартные выражения:

  • Это всем очень хорошо знакомые — «Переменные, знаки операций, проверки, циклы, методы, экзепшены, etc..». Оставляю на самостоятельное изучение.


Возможности:

  • Объектные — Владение низким уровнем для вас ограничено, FFI является исключением и может сломать ваш код, но это контролируемо. Никаких глобальных переменных и функций.
  • Ссылочные — построены на нескольких базовых концептах и для контроля (Гарантии) используются 3-х буквенные ключевики.
    • iso — Полная изоляция, другие переменные не смогут иметь доступ к этим данным. Может быть изменена, как вашей душе угодна и передана в другие акторы.
    • val — Неизменяемые данные, соответственно переменная под данной защитой доступна для чтения и может быть передана в другие акторы.
    • ref — Изменяемые данные, можно вертеть в любые стороны и иметь несколько переменных на эти данные, но не возможна передача в другие акторы.
    • box — Это совокупность val и ref, в зависимости от обстоятельств. Если данные используются только для чтения, то переменная на них ведет себя, как val и может быть передана в другие акторы. Однако, если вы пробуете записать новые данные в нее, то получаете ref и не возможность использовать между несколькими акторами.
    • trn — Данные, в которые можно писать постоянно, но в другие переменные отдается, как box. В последствии вы можете поменять ограничитель на val и передать в другие акторы.
    • tag — Идентификация данных, вы не можете писать в них или читать, но вполне возможно хранить и сравнивать для определения типа данных. Возможна передача в другие акторы.

    String iso // An isolated string
    String trn // A transition string
    String ref // A string reference
    String val // A string value
    String box // A string box
    String tag // A string tag
    



Привлекательность языка


Сборщик мусора

На борту мы имеем очень крутой GC, который является полностью конкурентным и не имеет Stop the World. На самом деле там их 2, один является сборщиком ссылок для каждого созданного актора и один глобальный.

Скорость акторов

Благодаря такому парню, как Дима Вьюков, который внес огромный вклад в lock-free алгоритмы и Go — появилась база, на которую делал упор Pony при разработке общения акторов. И именно поэтому сейчас скорость передачи между акторами достигает 20кк в секунду, а создание может достигать 1кк в секунду.

Прозрачная конкурентность

Это понятие дал я сам и был удивлен, когда для того, чтобы сделать код конкурентным — нам потребуется всего лишь поменять название функции. Этот способ еще более современней, чем предоставил Go со своими горутинами.

Пейперы



Статус и дополнительные ссылки


Язык находится в статусе далекой беты, сейчас версия языка 0.2.1. Разработчики на данный момент заканчивают остальные планируемые фичи, исправляют баги и стабилизируют язык. Плагины есть почти под все популярные редакторы.



Благодарен, что вы прочли статью и, возможно, заинтересовались языком.
Tags:
Hubs:
Total votes 48: ↑36 and ↓12+24
Comments24

Articles