Пользователь
8,0
рейтинг
3 октября 2014 в 13:11

Разработка → Свежий взгляд на Rust перевод

Я программирую на Rust уже достаточно давно, но на самом деле это не имеет большого значения. Rust настолько динамичен, что стоит отвлечься на пару месяцев, и придётся писать уже на фактически другом языке. Однако одна вещь остаётся неизменной: вектор развития. С каждым обновлением, каждой модификацией язык становится всё лучше и лучше.

Изменениям всё еще не видно конца, но даже сейчас язык уже кажется более стабильным, чем несколько месяцев назад, и начинают появляться некоторые устойчивые шаблоны проектирования API. Я подумал, что настало время исследовать всё это поглубже и решил переписать мою библиотеку для redis.

Где ниша Rust?


Больше всего я работаю с тремя языками программирования: Python, C и C++. С последним у меня очень противоречивые отношения, потому что я никогда не уверен какую часть языка я должен использовать. Си прямолинеен, потому что прост. С++ же заключает в себе кучу особенностей, среди которых ты выбираешь множество используемых тобой, и в тоже время практически гарантированно кто-нибудь другой выберет что-то другое. И хуже всего, когда начинаются холивары. Я одинаково не испытаю любви ни к STL, ни к boost, причём началось это еще до того, как я связался с разработкой игр. И каждый раз когда всплывает эта тема, находится как минимум один человек, который заявляет, что я неправ и не понимаю сути языка.

Rust для меня как раз вписывается в область использования Python, C и C++, но занимает эту нишу в разных категориях. Python я использую для написания как небольших утилит, так и масштабируемых серверных приложений. И он устраивает меня потому, что у него большая экосистема, и когда что-то ломается, это можно очень быстро отладить.

У Python, в отличие от других динамических языков, есть одна интересная особенность: он очень предсказуем. Может быть это из-за того, что я в меньшей степени завишу от сборщика мусора, чем в других языках: Python для меня равен CPython, a CPython подразумевает подсчет ссылок. Я тот человек, который разбивает циклы введением слабых ссылок, и который добавляет проверку на количество ссылок до и после запроса, чтобы убедится, что циклы не образовываются. Почему? Потому что мне нравится, что можно объяснить, как работает система. Я не настолько сумасшедший, чтобы отключать cycle collector, но я хочу, чтобы всё было предсказуемо.

Да, Python медленный, у него большие проблемы с параллельным кодом, интерпретатор слабоват и иногда кажется, что он должен работать по-другому, но на самом деле мне это не доставляет больших проблем. Я могу что-то запустить, уйти на месяц, вернуться – и оно всё еще будет работать.

Rust повёрнут на работе с памятью и данными, в чём очень похож на С и C++. Но в отличие от этих двух языков он куда больше похож на Python с точки зрения программирования API из-за вывода типов и отлично написанной стандартной библиотеки, которая удовлетворяет все нужды программиста.

Биться об стену


Забавно, что в начале программирование на Rust похоже на постоянное битьё об стену. Да, это не Python, и множество вещей, привычных для него, не работают в Rust. В то же время это не C++, так что проверка зависимостей станет вашим самым большим врагом. Вы будете часто задумываться: ведь это же должно работать, так какого чёрта эта тупая штуковина думает, что знает что-то лучше меня, и запрещает мне это делать?

Правда в том, что borrow checker не идеален. Он защищает от опасностей, но порой слишком многое запрещает. Исходя из своего опыта, я могу сказать, что он на самом деле неправ гораздо реже, чем вы предполагаете; просто нужно начать думать немного по другому. И самое главное, что он порой предотвращает самые опасные ошибки проектирования, которые потом сложнее всего исправлять. Python использует GIL для работы с потоками, и он там действительно необходим с момента появления самого языка. Интерпретатор написан таким образом, что сейчас уже практически невозможно ничего исправить.

Если постараться, то можно ошибиться с принятием решения при распараллеливании и в Rust, но для этого действительно придется постараться. Язык заставляет больше думать, и я считаю, что это хорошо. Я не хочу опускаться до проповедования тезиса «ООП – ошибка на миллиард долларов», но считаю, что код, который пишут люди, по большей части зависит от языка программирования. Мы пишем объектно, потому что это просто в C++, Java, Python. Ага, и птицы становятся объектами класса «Животные». Если же отобрать такой инструмент, то ты начинаешь мыслить немного по другому, и это хорошо. Мощности CPU уже растут не так быстро, и уже бессмысленно рассматривать только один объект в единицу времени. Приходится больше рассуждать о коллекциях и необходимых преобразованиях.

Rust вдохновляет


Мне программирование на Rust приносит радость. Да, я до сих пор не могу согласится со всем, что язык заставляет меня делать, но могу сказать, что уже давно не получал так много удовольствия от программирования. Язык даёт мне кучу новых идей для решения проблем, и я просто не могу уже дождаться стабильного релиза.

Rust вдохновляет по многим причинам. И главная из них – он практичен. У меня есть опыт работы с Haskell, я пробовал Erlang, и ни один из них не похож на практичный язык. Я знаю, что множество программистов обожают их, но эти языки явно не для меня.

Rust же одна из тех вещей, которую может попробовать каждый, и это будет весело. Во-первых (пока вы не наткнётесь на баг компилятора), он не будет крэшится. И будет выдавать милые сообщения при ошибках компиляции. И еще у него есть менеджер пакетов с отслеживанием зависимостей, так что можно начать использовать чужие библиотеки не боясь наткнуться на поганую или уже несуществующую экосистему. Работа с пакетами в Python достаточно сильно эволюционировала за последние несколько лет, но это всё еще одна из самых разочаровывающих его частей. Cargo, пакетному менеджеру Rust, всего полгода, но у него есть постоянный мейнтейнер, и его классно использовать.

Даже инсталлятор высшего качества. Он предоставляет компилятор, утилиту для документирования и пакетный менеджер. И большой вклад в удовольствие от программирования привносит как раз инструмент для работы с документацией, который рождает отлично выглядящую справку «из коробки». Хотя я и хочу, чтобы он был чуть более похож на Sphinx, чем на javadoc, это действительно хороший задаток на будущее.

Но самое интересное в Rust – это мелочи. Когда я только начинал играться с ним, я был поражен хорошей поддержкой FFI: кроме того, что можно просто вызывать что-то из сишных библиотек, компилятор сам их находит и линкует. И таких вещей в языке запрятано неописуемое множество. Есть макрос include_str!, который прочитает файл во время компиляции в строку в бинарнике, вау! И ведь можно даже затянуть переменные окружения в исполняемый файл, например.

Проектирование API


Самое занимательное сейчас в работе с Rust – это поиск пути правильного и красивого написания API. Rust как язык несомненно сложнее многих других именно с этой точки зрения: как программист вы будете разрываться между написанием прямолинейного (как в языках системного программирования) и предоставлением красивого высокоуровневого интерфейса (как в Python).

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

Одна из таких «плюшек» – это чертовски классная система типов. Язык статически типизированный, но механизм выведения типов позволяет писать действительно красивый код. Например, мой драйвер для Redis позволяет писать так:

extern create redis;

fn main() {
    let client = redis::Client::open("redis://127.0.0.1/").unwrap();
    let con = client.get_connection().unwrap();

    let (k1, k2) : (i32, i32) = redis::pipe()
        .cmd("SET").arg("key_1").arg(42i).ignore()
        .cmd("SET").arg("key_2").arg(43i).ignore()
        .cmd("GET").arg("key_1")
        .cmd("GET").arg("key_2").query(&con).unwrap();

    println!("result = {}", k1 + k2);
}

И для сравнения код на Python:

import redis

def main():
    client = redis.Redis('127.0.0.1', 6379)
    pipe = client.pipeline()
    rv = pipe \
        .set("key_1", 42) \
        .set("key_2", 43) \
        .get("key_1") \
        .get("key_2").execute()
    k1 = int(rv[2])
    k2 = int(rv[3])
    print 'result = {}'.format(k1 + k2)

if __name__ == '__main__':
    main()

Интересно, что хотя библиотека на Rust по размеру и «чистоте» походит на библиотеку на Python, она куда более низкоуровневая. Питоновская библиотека даёт каждому вызову отдельный метод, версия для Rust (потому что она молодая) – просто обёртка для low-level API, и запрос приходится создавать вручную как последовательность вызовов для каждого аргумента. Тем не менее конечный результат для пользователя выглядит так же хорошо. И всё же Rust требует немного больше обработчиков ошибок (хотя я избегал этого использованием unwrap, который заставляет приложение завершаться, но то же самое происходит и в версии для Python, где я так же пропускал проверку ошибок).

Большой плюс в пользу версии для Rust – типобезопасность. И это при том, что в общей сложности есть всего два места, где упоминаются типы, причем это те же самые места, где даже в Python использовалось приведение к целому.

Однако это не лучшее, что мы можем сделать с помощью Rust: у него есть расширения компилятора, которые открывают целое море возможностей. Например, есть библиотека, которая проверяет команды Postgres SQL на правильность, rust-postgres-macros:

test.rs:8:26: 8:63 error: Invalid syntax at position 10: syntax error at or near "FORM"
test.rs:8     let bad_query = sql!("SELECT * FORM users WEHRE name = $1");
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

И вот это действительно захватывающе.

P.S. Пообщаться на тему Rust API design можно в IRC-сети Mozilla на канале #rust-apidesign

Будущее


Настолько ли мощна концепция управления памятью в Rust, чтобы принять её как модель программирования? Я не уверен. Но я верю, что язык уже может стоять на ногах. И даже если народ решит, что borrow checker не нужен, мне кажется, это не помешает широкому распространению языка. Rust обещает быть отличным, и к тому же замечательно работает без сборщика мусора.

Это исключительный проект с открытым исходным кодом. И ему нужно больше помощи. Поддержка Windows становится всё лучше и лучше, но тем не менее требует много работы.
Перевод: Armin Ronacher
Egor Komissarov @komissarex
карма
50,0
рейтинг 8,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (78)

  • 0
    Rust, конечно, это клёво и всё такое, но я просто не могу заставить себя полюбить спецсимвольный ад именованных лайфтаймов или, например, местный вариант тернарного оператора let y = if x == 5i { 10i } else { 15i }.

    Возможно, это не будет так сильно заметно если реально писать на языке, да и прямой работы с лайфтаймами в коде Армина вроде не так уж и много, но пока подобный код вызывает приступы сомнения в новом убийце C++.
    • +6
      Это на многих языках так — не могу полюбить отступы в питоне, вызовы методов без скобок в руби. Но мы же понимаем что это фигня.
      С лайфтаймами конечно заморочка, но она же там специально, краеугольный камень так сказать.
    • +8
      Это всё-таки не вариант тернарного оператора, а популярная в функциональных языках идея, что каждое выражение возвращает какое-то значение. Например:
      let y = if x == 5 then 10 else 15 in (* ocaml *)
      let y = match x with | 5 -> 10 | _ -> 15 (* то же самое, только pattern matching *)

      auto y = [x](){if (x == 5) return 10 else return 15;}(); // аналог из C++
      • 0
        Я понимаю, но подобная запись — то, что предлагается использовать вместо тернарника. По крайней мере, обычный вид убрали именно из-за неё.
        • –1
          Мне кажется, что для таких вещей вообще надо заимствовать синтаксис перла, который, как правильно пишут комментом ниже, отчасти спародировали в питоне:
          doSomething() if x == 3;
          doOtherThings() unless x == 4;
          

          Для тернарного оператора, емнип, в перле как раз аналога нет, но подобная реверсивная запись для чтения достаточно удобна.
          • +1
            Для тернарного оператора, емнип, в перле как раз аналога нет


            Аналога нет, а сам оператор очень даже есть :)
          • –1
            В Перле это оператор, а в Пайтоне — выражение, так что не сказать, что это заимствование синтаксиса из Перла.
          • +1
            perl -e 'my $x = do { if (2+2==4) { 10 } else { 11 } }; print $x'
            10
            

      • +2
        Пайтон:
        a = 6 if x == 5 else 7
        
    • +1
      Честно признаюсь, что меня гораздо больше пугает версия для С++. Никак не могу запомнить, где там if, а где там else. А тут словами написано, не перепутаешь.

      Лично меня в Rust не радует синтаксис для задания типа, let x: i32. Но это дело привычки.
    • +2
      Как ни странно, это
      impl<'a> Map<&'a str, Value> for InfoDict {
          fn find<'x>(&'x self, key: &&str) -> Option<&'x Value> {
              self.map.find_equiv(key)
          }
          fn contains_key<'x>(&'x self, key: &&str) -> bool {
              self.find(key).is_some()
          }
      }
      

      эквивалентно этому:
      impl<'a> Map<&'a str, Value> for InfoDict {
          fn find(&self, key: &&str) -> Option<&Value> {
              self.map.find_equiv(key)
          }
          fn contains_key(&self, key: &&str) -> bool {
              self.find(key).is_some()
          }
      }
      

      благодаря lifetime elision :) как видите, от аннотаций почти ничего не осталось. Видимо, автор redis-rs не успел обновить код или проглядел этот кусок.
    • 0
      Тут в чём фишка — это не отдельный тернарный оператор (выражение), альтернативный обычному оператору (набор инструкций).
      Это общая форма, не нуждающаяся в отдельном представлении.
      Ну вот немного с потолка пример, но наглядно иллюстрирующий

      let y = if x >= 5 { let b = 3; x * b } else { let b = 100; b / x };

      А внутри можно и цикл прокрутить, если надо, и флаг какой-нибудь установить.
      В языках не поддерживающих такое смешение короткий тернарный оператор сразу рассыпается на несколько строчек.
  • +4
    Язык очень интересный, но синтаксис меня местами огорчает. Самый лучший синтаксис из си-подобных языков пожалуй у C#. Rust претендует на низкоуровневость Си (и еще очень интересно что в итоге получится со встроенными «умными указателями»), Go содержит интерейшие концепции эмбеддинга вместо наследования и интерфейсов, в D весьма много мелочей, которые упустили в С++; в общем, идеального языка опять нет.
    • –10
      У Swift очень классный синтаксис, но Apple пока ничего не говорила о его стандартизации или портировании.
      • +1
        Он не далеко уехал от Rust или Go.
        • –14
          Всё главное, как известно, кроется в деталях. А в деталях (синтаксис) Swift делает и Rust и Go. Причём, если Go имеет чётко выраженную специфику (многопоточность), то Rust вообще ни то ни сё.
          • +4
            Rust вообще ни то ни сё
            Ох, действительно? Почитайте
            • –15
              Действительно. Дальше Mozilla он не выйдет. Можете вернуться к этой ветке через 5 лет и посмотреть, кто был прав.
              • +6
                Ого! Да вы, прямо, Нострадамус! Может, все же поделитесь подробностями, на чем основаны ваши предсказания? Это ж, все-таки, Хабр, а не «Битва экстрасенсов».
                • +1
                  Если без перехода на личности, то моё мнение основано на аналогии с Vala, тоже как бы язык общего назначения, но за пределы GNOME не вышел.
                  • +1
                    Ну, знаете, можно привести множество аналогий, которые «вышли или не вышли за пределы». Но как это будет связанно именно с Rust? И как можно, основываясь на этом, делать такие категоричные утверждения?
                    P.S. У меня не было цели вас обидеть переходом на личности, если что. Там, в моем комментарии, предполагается смайлик. Что я в действительности хотел узнать — это то, насколько обоснованы ваши предсказания.
                    • 0
                      Достаточно посмотреть первую двадцатку на той же Tiobe, чтобы увидеть, что большинство из широко ныне используемых языков имеют в общем-то примитивный синтаксис, за редким исключением. Сложный язык = дорогой код.
                      • 0
                        Тут не поспоришь. До тех пор, пока заказчики не начнут подсчитывать убытки от позднего обнаружения багов, для них главным аспектом будет скорость и лёгкость разработки. Надеюсь, они таки образумятся ;)
                  • +8
                    А Objective C не вышел за пределы Apple.

                    У Rust, тем временем, есть перспектива заменить C/C++ в системном программировании. Большая такая ниша.

                    А что Swift? Очередное apple-only решение, с нескучным синтаксисом и набором фич из других языков.
                    • 0
                      Objective C слишком ужасен, чтобы его добровольно использовать (имхо). Swift вообще-то LLVM-язык, так что больших проблем портировать его практически as is в данный момент нету. Вопрос в том, будет ли это сделано.
                      • 0
                        Есть мнение, что в Objective C объектный подход более «трушный», чем в том же С++ и Java. Лично мне, кстати, многие вещи в нем очень сильно понравились, хотя опыт использования его в реальных проектах у меня не очень большой. Единственное, что меня удержало от полноценного обширного использования Objective C — это его некроссплатформенность. Точнее, отсутствие полноценной стандартной библиотеки (какой-то части Cocoa, не связанной с GUI) на других платформах. Так что зря вы так о нем )
                        • 0
                          Ну, это конечно на вкус и цвет.
                      • 0
                        У Objective C синтаксис непривычный, хотя концептуально это очень интересный язык — не менее интересный чем Rust и Go (а в чем-то даже и более). А вот у Swift к сожалению, насколько я понял, синтаксис привычный, а многих интересных возможностей ObjC (пока еще?) нет.
                        • 0
                          Это какие, например?
                          • 0
                            По крайней мере в руководстве по Swift я не нашел упоминаний динамических возможностей — все что связано с отправкой сообщений (я подозреваю что отправка сообщений используется неявно — но я ожидал увидеть возможность явно указывать вызов метода или отправку сообщения), также всевозможные добавления методов в классы на лету, доступ к метаинформации и т.д.
                            • 0
                              Насколько я помню — runtime у него общий с Objective-C, так что стандартные API уровня C должны работать.
                            • 0
                              промазал веткой
                            • 0
                              Для Obj-C классов (и совместимых с ними Swift-классов, т.е. помеченных атрибутом objc) ничего не меняется, всё те же трюки через Obj-C runtime. Также есть fine-grained контроль над динамикой, т.е. можно не помечать весь класс objc, а лишь пометить атрибутом dynamic нужные свойства или методы (то, что вы называете «возможность явно указать вызов метода или отправку сообщения»).

                              Для нативных Swift-типов действительно отсутствует интроспекция и подмена методов в рантайме, ибо методы либо биндятся во время компиляции (для структур, перечислений и private/final методов классов), либо используется vtable.
                    • 0
                      Добавлю: для Apple портировать и стандартизировать Swift было бы огромным вином, т.к. продвигая язык, продвигаешь платформу. Это отлично понимает например Microsoft, развивая свой C#.
                      • +7
                        Тогда яблочники-программеры перестали бы чувствовать свою элитарность, и Apple потихоньку начал бы терять лоск избранности… Я сейчас не стебусь и не издеваюсь. Я серьезно.
                  • +1
                    Нет, вокруг Vala такого хайпа, как сейчас вокруг Rust, не было.
                  • 0
                    Не слежу за Vala, но вот сразу вспомнил что есть Tox клиент, кросс платформенный, написанный на Vala: wiki.tox.im/Venom
          • 0
            Ну дак он немножко не кроссплатформенный, так-то можно б было спорить
            • –2
              Надеюсь, что пока. Выше написал, почему Apple выгодно его стандартизировать и портировать.
  • +33
    Rust настолько динамичен, что стоит отвлечься на пару месяцев...
  • 0
    Да, это не Python, и множество вещей, привычных для него, не работают в Rust.

    В смысле «не работают»? Нет нужных языковых конструкций? Или семантика операций другая? Приведите примеры, что-ли. А то совершенно не понятно о чем речь…

    И про практичность… Что вы понимаете под практичностью? Haskell и Erlang хоть и популярные, но довольно маргинальные языки с высоким порогом входа. Причем у Erlang'а высокий порог входа больше психологический, вызванный непривычным синтаксисом…

    Сравнивать с ними новые языки, это видимо мода такая. Какое-то время назад некий товарищ сравнивал с ними язык Go и делал очень странные выводы…
    • 0
      Это перевод.
    • 0
      Если, допустим, сравнивать с плюсами, то вот лично для меня реально порог входа в них оказался б0льшим, чем в хаскелл: он просто оказался легче в освоении. Что касается Эрланга, то отовсюду народ пишет, что срок освоения его с OTP и плюшками, исчисляется двумя неделями… одним месяцем. В то время как плюсы на нормальном уровне — это годы. Так что про высоту порога вы, на мой взгляд, приврали.
      • 0
        Дык, про Erlang я так и написал, что порог входа скорее психологический чем реальный…

        На счет C++ и Haskell тут я думаю проблема в бэкграунде… Я например начинал с ассемблера и обычных процедурных языков программирования, типа Паскаля, Модулы-2 и прочая. Для меня в C++ главной проблемой было перестроиться на объектно-ориентированное мышление и не увлекаться строительством иерархий…

        Сами конструкции C++ никаких проблем не вызывали. Пока компиляторы были не особо оптимизирующими, я знал какая конструкция в какой набор машинных команд преобразуется с точностью до перестановок, что таблицы виртуальных функций это банальная косвенная адресация, в каком сегменте данных хранятся константы, какие значения будут в стеке, какие в хипе и тому подобное…

        У вас очевидно другой бекграунд… )
        • 0
          моя приблизительная последовательность изучения языков программирования:
          spectrum basic -> qbasic -> object pascal -> c -> assembler -> lisp -> haskell -> visual basic -> erlang -> java -> c# -> prolog -> Objective c -> c++ ->…
  • +12
    Я очень жду, когда он повзрослеет. Потому что главная беда индустрии — за столько лет никто не сумел стать Си. Это означало, что всё большее число нового кода «нагибалось» под Си, обрастая всякими синтаксическими ужасами (только потому что в Си этого нет, хотя и могло бы быть без раздувания рантайма — например, возврат нескольких значений из функции).

    Я думаю, как только он повзрослеет, нас ждёт множество, наконец-таки _быстро_ работающего и быстро пищущегося софта, способного работать в нативном режиме (ELF-файл).
    • 0
      Go ИМХО сейчас лидирует, пользуясь мощной PR-поддержкой Google. Хотя лично я бы предпочел на его месте видеть D.
      • +5
        Ни тот ни другой не годятся как замена C — это уже много раз обсуждалось.
        C это прежде всего прозрачная и полностью контролируемая работа с памятью, возможность работать без библиотеки, стандартный ABI.
        • 0
          А вот по этому поводу не затруднит показать подробный разбор что именно нельзя сделать на rust?
          • 0
            Я про Go и D
            • 0
              Ну, на D есть, например, вот это github.com/JinShil/D_Runtime_ARM_Cortex-M_study

              Понятно, что стандартная библиотека пролетает, но никто вроде не мешает написать свою, не требующую кучи.
              • 0
                Это понятно. Но тут всё же требуется run time поддержка, без нее половина фишек языка перестает работать. И писать её для нестандартных случаев нужно самому.
                Для rust же есть несколько возможностей:
                1. no_std — совсем без библиотеки(зависимости уровня компилятора stack_exhausted, eh_personality, fail_fmt)
                2. libcore — минимальная библиотека (дополнительно зависимости memcpy, memcmp, memset)
                • –1
                  А какого рода runtime поддержка требуется D? Я просто не в курсе, к сожалению.
                  • 0
                    В D по-умолчанию сборщик мусора, на который завязана вся стандартная библиотека.
                    • 0
                      Это, в моем понимании, означает, что «embeded-вариант стандартной библиотеки» еще не написан.
                      • +1
                        Ну, так можно сказать, что любой язык подходит для embeded, например ruby. Просто «embeded-вариант стандартной библиотеки еще не написан». В том виде, в котором он есть сейчас, язык D подразумевает наличие сборщика мусора, а значит для embeded не подходит. И ещё много для чего (например драйвера на нём не очень-то попишешь).
                        • +1
                          Ну, отчасти вы правы. Есть ведь и embedded python и java. И даже javascript.
                          Другое дело, что эти языки (особенно javascript) плохо подходят по другим причинам. В embedded хочется видеть тот же С, только безопасный.

                          Язык D не подразумевает наличие сборщика мусора, стандартная библиотека подразумевает, как вы сами сказали. Ссылку на минимальный рантайм я уже кидал. Вот если бы в D вообще нельзя было бы удалить объект вручную, без сборщика мусора, тогда я бы с вами согласился.

                          Собственно, по своему (не очень большому) опыту могу сказать, что в embedded и на С стандартная библиотека нужна довольно редко. И она тоже должна быть написана специально, хотя бы из соображений экономии памяти.
                          • +1
                            Совсем забыл отвестить, забегался.
                            В D поддержки runtime требуют например такиа вещи как структуры, классы, срезы. Это уже не совсем библиотека. В rust такие вещи решаеются либо на уровне языка, либо на уровне libcore(требующей минимальной поддержки со стороны libc либо самостоятельной реализации 3х функций работы с памятью).
                            P.S. с D на самом деле не сильно глубоко знаком — ничего больше 20 строк не писал, просто изучал из чистого любопытства
                            • 0
                              Т.е. в D нельзя создать класс или структуру, не имея сборщика мусора?
                              • 0
                                runtime != сборщик мусора.
                                dlang.org/struct.html
                                Структуры в D не совсем структуры в C/C++, отсюда и требование runtime.
                                Сомневаюсь, что вещи вроде dlang.org/class.html#SharedStaticDestructor можно сделать без runtime.
                                • 0
                                  del
                                • 0
                                  Я дико извиняюсь, но вынужден попросить у вас уточнить, что вы понимаете под словом runtime.
                                  • 0
                                    В первом приближении — набор функций, объединенных в библиотеку, вызовы к которым компилятор встраивает в исполняемый файл без явных на то причин/прямых упоминаний. Обычно таким образом реализуются работа с памятью и обработка исключений. Вообще на англоязычной вики вроде вполне нормально написано подробнее. en.wikipedia.org/wiki/Runtime_library
                                    • 0
                                      В таком случае, опять-таки, просто нужно написать embedded runtime. Для С и С++ стандартные библиотеки тоже приходится переписывать, тут ничего особенного нет.
                                      Вероятно, переписывать придется больше, чем для rust, но ничего невозможного или запредельно трудного я в этом не вижу.

                                      Насколько я знаю D поддерживает ручное управление памятью и подсчет ссылок, так что runtime без сборщика мусора тоже можно реализовать.
                                      • +1
                                        Ключевая фраза «просто написать».
                                        1) Нужно реализовывать
                                        2) Объем этого runtime выше, чем для rust и C, что для жесткого embedded может быть критично

                                        А так да, полностью согласен — сделать можно.
            • +4
              Go никогда не позиционировался как системный язык. Более того, он создан для конкретных задач и имеет концептуальные решения, которые за пределами своей ниши работать не будут.

              Например: го-рутины не вытесняются по времени. Переключение контекста происходит только при входе в системную функцию и при добровольной отдаче управления. Если рутина захочет крутить чисто математический цикл, никто ее не остановит и процессор данного треда будет занят только исполнением этой рутины (хотя на тред может быть повешено еще несколько).

              Это решение удобно своей простотой и скоростью в сравнении с чистыми тредами и interpreter-based подходом, когда безусловное переключение происходит после интерпретации очередных N байткодов.

              Плюс к этому, управление памятью подразумевает наличие рантайма, невозможность использования библиотек в текущей реализации (все компилится в кучу) и многое другое.

              Еще раз повторюсь — решения вполне оправданы в рамках своей предметной области, но просто так взять язык и пересадить его в другую среду нельзя.
      • 0
        В этом и проблема — сегодня там мощная PR-поддержка, а завтра «закрываем, чтобы сфокусироваться на G+». Язык, за которым стоит коммерческая компания имеет дурноватый оттенок.
        • 0
          Не, тут опенсорс и приличное комьюнити. Это вам не «гугльридер» какой-нибудь, закрыть так просто не получится.
          • 0
            На раз-два-три. Гугль делает следующую версию проприетарной, старую форкают, а гугль вносит несколько несовместимых изменений.
            • 0
              Гугль, конечно, те еще засранцы, но такой сценарий — вряд ли. Да и смысла нет.
              • 0
                А есть смысл закрывать фидреадер и поиск по коду? Та же гребанная логика вокруг г-.
      • +7
        Напомните, как помогла PR-поддержка Гугла Dart'у?
        • 0
          Ну вообще в том же TIOBE Dart уже умудрился влететь в топ-20. Хотя тот же Go болтается на 42-м. Но рейтинги (тем более для ЯП) — это зло, конечно же.
  • 0
    borrow checker это проверка корректности использования общих ссылок на этапе компиляции?
  • 0
    Странно, то что Rust сравнивают с Python или С++

    Прочитав пару статей по Rust, пришел к выводу, что его синтаксис ну очень похож на синтаксис Scala, также в нем практикуются те же подходы, что и в Scala, такие как pattern matching, Option и т.д

    • +1
      Скорее, и Rust, и Scala позаимствовали эти концепции из более ранних языков вроде ML или Haskell :)
      • 0
        Согласен, так будет более правильно сказано.

        В целом концепт языка мне очень импонирует, но все же хотелось бы узнать область применения данного языка. Если например Scala может быть легко добавлена в текущий Java-проект или полностью заменить Java код, при этом можно легко использовать широкую набор Java-библиотек, то с Rust неясно в каких проектах его будут использовать и для каких целей. Особенно интересует вопрос интеграции с другими языками

        • +1
          Rust позиционируется в качестве замены C/C++ — это низкоуровневые библиотеки, embedded, игры. Однако Rust предоставляет достаточно абстракций, чтобы залезть и в нишу Go — это высокопроизводительный бэкенд. Например, уже сейчас есть несколько легковесных веб-фреймворков.

          Взаимодействие с кодом на C в Rust близко к идеальному (имхо). Проблемы там есть, насколько я помню, только в районе юнионов. С C++ сложнее, но тут уже особенности самого C++ и его всевозможным vendor-specific ABI.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.