Pull to refresh

Comments 51

Когда я первый раз увидел bin, у меня первый раз возникло желание написать свой язык. Там были просто гениальные идеи, и были такие как синтаксис вызова методов. Когда метод может быть вызван четырьмя вариантами, пример есть в почте автора, у вас будет четыре не пересекающихся группы программистов на нем. Почему это плохо.
Вспомните почему заказали Perl.

Почему не пересекающихся? :) Я в проекте использую 3 из 4 перечисленных.


Ну например для логирования я не использую скобки:


logging.debug "Oops"  # better
logging.debug("Oops")  # worse but not restricted
"Oops".debug()  # wat
"Oops".debug  # insane

Type convertion удобно писать так:


someProc(10.unit8)  # better
someProc(unit8(10))  # worse but not restricted

Для методов (т.е. процедур, которые относятся к какому-то объекту) я использую первое:


someObject.someProc(arg1: 5, arg2: 10)  # better
someProc(someObject, arg1: 5, arg2: 10)  # worse but not restricted

Т.е. правило "пиши как лучше читается". Хорошо это или плохо — пока не знаю, но более склоняюсь к "строгому" языку, чем к таким вольностям.

Т.е. правило «пиши как лучше читается». Хорошо это или плохо — пока не знаю, но более склоняюсь к «строгому» языку, чем к таким вольностям.

А для меня это киллер-фича. :) Самое главное для меня — это как логично(и быстро) читается исходник.

И по поводу отступов — вот тут как раз «строгость» в тему. Это тоже в плюс читаемости.

Функции можно вызывать как методы и в D. Так что, такая киллер-фича не уникальна

Это называется UFSC
Для ФП стиля очень удобно.

Вообще, Nim стоит поздравить с релизом.

Это называлось UFCS в ниме раньше. Потом они стали называть это Method Call Syntax. Потому что могут ¯_(ツ)_/¯

Было бы неплохо выделить киллер-фичи Nim, для тех кто не может выделить их сам из статьи, например для меня)

Сильвупле (имхо):


  1. Быстрая компиляция в быстрый нативный код
  2. Доступна вся экосистема C/C++
  3. Простой в освоении
  4. Позволяет писать код любой сложности

Если С++ ругают за медленную компиляцию, то как компиляция Nim (которая ведь транспиляция в С++ сперва) может быть быстрой?

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


struct tySequence__K284t8D0DApfLbw9c7cpnKw {
  NI len; tySequence__K284t8D0DApfLbw9c7cpnKw_Content* p;
};
struct NimStrPayload {NI cap;
AllocatorObj* allocator;
NIM_CHAR data[SEQ_DECL_SIZE];
};
struct NimStringV2 {NI len;
NimStrPayload* p;
};
typedef N_NIMCALL_PTR(void, tyProc__l0xby6CKnyVDN9bJs3WwRgw) (NI16 entity);
typedef NU8 tyEnum_Level__pW4mH4lipH6u2NKDGEWdGg;
typedef NimStringV2 tyArray__nHXaesL0DJZHyVS07ARPRA[1];
struct TNimType {void* destructor;
NI size;
NCSTRING name;
void* traceImpl;
void* disposeImpl;
};

Но это не точно.

В целом логично, спасибо. Вероятно, генерированный код просто не будет особо напирать на "тяжелые" фишки из С++.

Медленая компиляция идет в основном от сложного использования шаблонов. Если nim генерирует простой C-подобный код с минимальным использованием фич из C++ компиляция будет вполне быстрой.

Ну, да, я вроде уже сам додумался чуть выше, спасибо :)

Позволяет писать код любой сложности

Любой тьюринг-полный язык позволяет писать код любой сложности

Согласен, тут не хватает какого-то слова, но мне казалось, что статья доносит посыл.


Позволяет эффективно писать код любой сложности.

Как вы на Питоне напишете драйвера для принтера?

А что? Не знаю, как в Linux, но в Винде драйвер принтера это user-mode program. Оберточку сделать и все, запускай Питон

Не то, чтобы стоит так делать, конечно

Итак, у нас есть функции, процедуры, дженерики, мультиметоды, шаблоны и макросы. Когда лучше использовать шаблон, а когда процедуру? Шаблон или дженерик? Функция или процедура? Так, а макросы?


Функции, процедуры, дженерики, мультиметоды, шаблоны, макросы.
Именно в таком порядке по приоритету. Если первого пункта недостаточно для реализации необходимого функционала, переходим к следующему и так далее. К сожалению, не могу вспомнить где в документации видел приоритетность, но она была очень похожа на эту. Разве что мультиметодов и функций там не было. Мультиметоды я бы вообще исключил, поскольку они почти всё время были сломаны.

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


Например, сначала у меня был бесконечный цикл (gamedev, как-никак), который был функцией, принимающей коллбек:


proc loop(frequency: float, callback: proc(dt)) =
  # ...
  var dt = ...
  callback(dt)

proc doSmth(dt: float) =
  echo &"{dt} seconds passed in this loop iteration"

loop(30, doSmth)

А потом я вдруг понял, что с шаблоном будет проще и быстрее:


template loop(frequency: float, code: untyped) =
  # ...
  var dt {.inject.} = ...
  code

loop(30) do:
  echo &"{dt} seconds passed in this loop iteration"
Nim не первый и не лучший(ИМХО)кто пытается сделать ядреный сплав простоты и эффективности (Pythonic-like, macros, compiled,..). Был такой Boo (остановился в 2010 из-за перехода автора в Unity), имел на 25% короче синтаксис, макросы, работал на .Net. Все было круто до 2010, поддержка со стороны SharpDevelop лучше чем у Nim сейчас. Был Nererle c директивой pragma=indent программы были размером равны аналогу на Python, царь метапрограммирования. Убит Microsoftом ввиду опасности для С# и F# и прочих его унылых языков. Авторы взяты на работу в MS на левые проекты за мешок денег. Cobra,… все ушли. Слишком инертный мир в программинге. Слишком.
C#, F#

Вот так, через запятую? Вы F# хотя бы издалека видели?

Тоже вспоминаю Nemerle. Очень жаль, что закопали. По сей день смотрится очень круто.

К сожалению, поддержка от Status проекта nim не вечна. Работал там, в течение последнего года компания оптимизируется и оптимизируется, судя по финансам, в новом году оптимизируется окончательно.
И это определённая проблема nim. Интересный язык, но нужна поддержка компаний.

В точку. Сравнивая с rust, я прям вижу, как проекту не хватает внимания, как со стороны разработчиков, так и со стороны компаний.

>внимание со стороны разработчиков

я сколько ни смотрел на ним, я не понял, зачем он. точка.

нужен понятный таргетинг и обоснование

Ну, знаете… Зачем плюсы?

Десктоп, веб, эмбеддед, энтерпрайз, геймдев, расчеты — а что может Ним?

Для каждой области нужен свой тулинг, библиотеки

Скажу так: ним может всё, что могут C и C++. По собственному опыту не могу сказать, что есть прям какая-то ниша — nim это general purpuse.
Desktop — да, есть несколько библиотек для гуя, но можно написать свой враппер для любой либы из c/c++.
Web — есть jester и karax (фреймворки на ниме), есть всякие сокеты и вебсерверы в стандартной библиотеке. Но можно написать свой враппер для любой либы из c/c++.
Эмбеддед — можно, там надо спец флаги указать.
Геймдев — можно, пишу сейчас сам. Ядро на ниме, графика — на ogre3d или sdl, ввод и окна — на sdl, сеть — на enet (но есть и сетевые библиотеки на pure nim).
Расчёты — есть куча всего, типа arraymancer, neo и что-то ещё. Но можно написать свой враппер для… Вы поняли :)


Конечно, хотелось бы видеть всё на чистом ниме, но это утопия, для этого нужно большое комьюнити, которое это всё напишет, а чтобы было большое комьюнити, нужно чтобы много всего было написано.

Что меня больше всего поразило в Nim, когда я некоторое время назад на него смотрел — то что язык позиционируется как замена C/C++ и при этом там есть сборка мусора (но уже какбы нет), причем там целая куча разных сборщиков на выбор, но ни по одному не найти нормальной документации, того какие гарантии риалтайма даются, и как они обеспечивается.

image

Вот эта картинка с их сайта на самом деле сделана с отключенным сборщиком циклов, по сути это просто reference counting. Я понимаю что технически это тоже «сборка мусора», но нельзя просто одно заменять на другое, нужно чтобы программы изначально писалась с учетом этого.

Сейчас автор языка решил всё таки сделать reference counting основным режимом, но из-за этого почему-то отвалилось куча всего и вылезло дикое количество багов. Очень странно называть язык в таком состоянии 1.0.

Стоит отметить, что в версии 1.0 по умолчанию старый сборщик мусора, с которым всё норм. Новый сборщик ещё не пришёл на замену, он включается опционально. Проблема именно в количестве сборщиков мусора (при том они разные: shared heap vs per-thread heap), и в том, что сейчас появился ещё один, вместо того чтобы делать реально полезные вещи.

Со старым сборщиком не норм то, что когда новый доделают, старый скорее всего выбросят (задепрекейтят). А с новым не то, то что его непонятно когда вообще доделают. Поэтому реально полезно было бы доделать это до конца.
Извиняюсь, что отвечаю на комментарий полугодовой давности, но ARC это таки очень полезная вещь — ARC это по сути вставка компилятором различных хуков типа =destroy, = и так далее (всё это происходит благодаря compile-time data flow analysis и компилятор создаёт CFG), и reference counting. ARC и не будет дефолтным, т.к. он не может работать с циклами — для этого есть ORC (это ARC с добавленным собирателем циклов).

В ARC есть shared-heap, не нужно каких-то setupForeignThreadGc или похожих для работы с C библиотеками (или наоборот, если нужно писать shared библиотеку на Nim), ARC намного лучше для embedded.

Пока что планируется, что в 1.4 (может и позже, не знаю) ORC станет дефолтным GC (но это произойдёт как минимум тогда, когда сам компилятор будет работать с ARC/ORC и все популярные библиотеки).

Ещё с ARC возможно больше потенциальных оптимизаций благодаря анализу использования данных, к примеру вот самый недавний PR насчёт создания оптимизатора для ARC — github.com/nim-lang/Nim/pull/14962

Больше информации — www.youtube.com/watch?v=aUJcYTnPWCg (презентация Andreas'а с NimConf об ARC/ORC), forum.nim-lang.org/t/5734 (там в постах много интересного), nim-lang.org/docs/destructors.html про деструкторы (они являются важной частью ARC)
UFO just landed and posted this here
Эти картинки доверия не вызывают. Особенно HellWorld binary size. Для D/Rust так точно липа (

Наверно, как обычно, нубобенчмаркеры с компиляцией по умолчанию. Именно так и написано =)
what are the typical flags an application is compiled under

А лаги ГЦ так типичные для RSS 1.5-2Гб
UFO just landed and posted this here

Самое яркое впечатление от моего опыта с nim: ты пытаешья сделать что-то незадокументированное (или просто совершаешь ошибку) и в ответ получаешь километровый стектрейс… который абсолютно нечитаем и абсолютно не помогает в решении проблемы. И приходится разбираться в этом самом "фрактале сложности", не всегда с успехом.


Следствие от того же самого: если какая-то фича в библиотеке не задокументирована, то понять, как её использовать можно только с очень большим трудом (исходники не особо-то и помогают).

Возможно, сейчас с этим лучше. Километровые стектрейсы появляются, если всё падает в gcc, и да, это больно отлаживать. В самом же ниме ошибки вполне понятные и лично я с ними не так часто встречаюсь.

но вообще я просто хочу сесть и ехать (причём быстро) на вечеринку. Машина — не цель, а средство достижения цели.

но от этого у меня отваливается багажник. И знаете что? Мне всё равно чертовски нравится эта машина, ведь это лучшая из всех машин, что я видел.

Но приходится бросать ее на обочине и ехать на вечеринку на другой. :)
Ох и намучился я тоже с глюками Nim. Даже при том, что очень хочется этот язык использовать, вышеупомянутые минусы заставили его отложить в сторону.

Нет, на другой (c++) я бы так далеко никогда не доехал :)
Жаль, что у вас был негативный опыт. Попробуйте v1 — всё-таки разрабы проделали много работы над стабильностью. Я тут конечно угораю над ними в статье, но вообще стало лучше.

Есть шаблоны (templates) — механизм замены, но не такой блевотный, как в C++ (там это всё ещё просто текстовая замена, или уже что-то поумнее?).

Так, а чем плохи шаблоны в плюсах? Имхо явно лучше, чем в этом вашем nim, где можно пихать что угодно куда угодно.
Вообще от nim осталось впечатление какого-то франкенштейна, который сам не знает чем является.
По моему мнению шаблоны в плюсах плохи:
1. Временем компиляции
2. Негибкостью (хороши только если одну функцию надо написать для нескольких типов, но как только начинают решаться проблемы из реального мира, приходится изобретать монструозную конструкцию из шаблонов, а то и вообще откатываться к макросам из C)
3. Сообщениями об ошибках (без парсера в них можно утонуть)

В Nim метапрограммирование на порядок лучше плюсового реализовано.

Я извиняюсь, кажется, я налажал в терминологии. Я имел ввиду механизм подстановки, когда пишешь #define one two, и препроцессор не глядя заменяет одно на другое. В Ниме templates — шаблоны — как раз делают постановку кода, вот меня и переклинило.
Если я всё правильно понял, то шаблоны из c++ — это generic в ниме.

В C++ шаблоны позволяют подставлять в код типы или значения времени компиляции (constexpr).


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


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

Какого размера получается файл, насколько больше он потребляет оперативной памяти, по сравнению с C? Используется трансплайнер в по-настоящему нативный C-код, или же используется некая стандартная библиотека от nim при компиляции? Может ли nim заменить C в embedded, когда нужно запускать программу на устройствах с 4 МБ ROM и 32 МБ RAM, при том, что занято из этого уже половина?
Минимальный hello world получается размером в 80 КБ, линкуется с libc. Думаю, жить можно.
Извиняюсь за бамп старого треда, но таки с LTO (который по сути можно «бесплатно» использовать с Nim, так как он компилируется в С) и статической линковкой с musl можно получить бинарники меньше 40-30кб, а так ещё если использовать LTO, ARC и --panics:on -d:noSignalHandler --opt:size при статической линковке с musl, то у меня от echo «Hello, world!» выходил статический бинарник <10кб размером :)

Ни про какую стандартную либу я не слышал, вроде просто компилируется в c (или cpp) и оно самодостаточно.
По поводу размера — нет предела совершенству: https://hookrace.net/blog/nim-binary-size/

Последний раз, когда я смотрел Nim, там не было ни интерфейсов, ни трейтов. Для их эмуляции предлагалось руками собирать структуру из нужных замыканий (найдено в недрах форума, ссылку сейчас не найду). Также несколько странное решение для discriminated unions в виде явно выделенного поля под дискриминант.
Как с этим сейчас?

Интерфейсов всё так же нет (ну или, как вы и говорили, собирать из замыканий, что я считаю извращением). Зато есть концепты, там много всего: https://nim-lang.org/docs/manual_experimental.html#concepts


Вообще не вижу проблемы с полем под дискриминант, даже не представлял что можно по-другому. А что не так?

Sign up to leave a comment.

Articles