Pull to refresh

Comments 19

Lua — язык, в котором всё доведено до ума.
Вы не могли бы слегка развернуть свою мысль? До чьего ума доведено, как вы измеряете степень доведённости до ума? Судя по тому что новые версии продолжают выходить, что-то там недоведено: www.lua.org/versions.html

Для меня Lua — это тот же JS. Строки, числа, key-value хранилище и указатели на функции. Всё, по большому счёту ничего больше в этих языках нет (да, я в курсе про всякие асинки, промисы и прочее. Это не основа языка, а так, второстепенные костыли которыми обмазали JS чтобы героически преодолевать его однопоточность)

Ну и соответственно почти все те претензии что у меня есть к JS так же применимы к Lua. Хотя бы даже идиотское правило что переменные по умолчанию попадают во внешнее пространство имён и надо писать var/local.

Ещё можно отметить то, что в таблицах нельзя хранить nil, зато отсутствующие в таблице ключи и неопределённые переменные имеют это значение. Иногда удобно, но слишком часто служит источником ошибок. Кроме того, языком полностью игнорируется расхождение в числе аргументов при объявлении и вызове функции — недостающие аргументы просто забиваются nil’ами (если только функция не с ... — тут вы всегда можете понять, использовали ли nil или просто не написали аргумент), «лишние» аргументы молча игнорируются.

>>Ещё можно отметить то, что в таблицах нельзя хранить nil, зато отсутствующие в таблице ключи и неопределённые переменные имеют это значение
я постарался отметить. Это очень печальная сторона языка в отношении отладки, но я на стороне тех людей которые не боятся применять Lua в качестве основы своего пользовательского интерфейса, да неофитам придется пройти нелегкий путь что бы начать чувствовать язык кожей, но я против мнения что Lua это «обмазанный другим Г js» — это совершенно другой язык, да с проблемами любого языка с неявной типизацией, но к счастью без необходимости в тройных равенствах (===).

На JS я практически ничего не писал, поэтому сравнить не могу. Но второе негативное ощущение от lua — это стандартная библиотека, выглядящая как куча недоделок:


  • Из всех возможных манипуляций с переменными окружения вам доступно только получение значения переменной. Получить полный список, а также добавить либо изменить значение нельзя.
  • Нельзя менять рабочий каталог.
  • Есть удаление каталогов, но рекурсивное удаление вам придётся писать самим.
  • Есть два способа запустить процесс, но ни одного — запустить со списком аргументов. Чего‐то вроде shellescape() тоже нет.
  • Нельзя запустить процесс в фоне и общаться с ним. Можно только либо читать его вывод (документация, кстати, не говорит о том, будет ли это stdout, stderr или оба сразу, но проверка показывает, что только stdout), либо писать ему в stdin.
  • В регулярных выражениях есть такие вещи как %{number} или %b(), но нет банального |. И ещё регулярные выражения не компилируются, так что вы можете только надеяться на оптимизатор, либо на то, что компиляция не занимает долгое время (что, скорее всего, говорит о низкой скорости работы результата).
  • Нельзя узнать число элементов в таблице. В т.ч., проверить не пуста ли она, не используя pairs().
  • Upstream нарушает обратную совместимость в минорных версиях. В частности, из‐за этого «нет» побитовых операций в стандартной поставке — обновляться с 5.1 просто нельзя, т.к. многие нужные пакеты забили на обновление. Команда luajit работает в этом отношении намного лучше.

Я не ожидаю Python’овского «batteries included», но мало что из того, что всё‐таки есть, выполняет свои функции полностью.


Ещё, я совершенно не понимаю, почему нельзя писать {}[key] и "%d":format(num) без дополнительной пары скобок. Полагаю, это потому, что func 'abc'.foo работает как (func('abc')).foo (с таблицей аналогично), но не понятно, зачем было делать выбор в пользу менее читаемого синтаксиса.

IMHO из вышесказанного реальной проблемой можно считать только не достаточно широкий формат регулярок, можно было обойтись и вовсе без работы с файлами, каталогами, командной строкой и прочими нехорошими связями с ОС, то что это добавили в принципе сильно навредило языку, чистый скриптовый язык не должен иметь этих костылей. Как рассчитывалось применение lua в реальных проектах — есть серьезный и полновесный базовый движок системы например реализованный на С++, имеется связка со скриптами и предоставлен набор импортируемых функций которые уже могут включать в себя все полноценные атрибуты «красивой жизни» свойственные профессиональному языку для той или иной платформы. Есть у вас полноценная рекурсивная функция обхода всего дерева каталогов реализованная на C++ которая запускается из скрипта и возвращает в скрипт уже набор формализованный данный в виде таблицы со всем результатом поиска. А дальше с помощью скриптов происходит расширение функционала без изменения базовой реализации на C++. Такой был замысел, ну а если вы пытаетесь писать на lua что-то самостоятельно то приходится довольствоваться малым… Что касается синтаксического сахара, что тут сказать — на вкус и цвет… Существование хоть какой-то связи с ОС делает возможным создания плагина ну скажем для VLC с элементами трояна-шифровщика, что как бы плохо.
Нельзя узнать число элементов в таблице. В т.ч., проверить не пуста ли она, не используя pairs().

Проверить таблицу на пустоту можно функцией next.
Размер массива можно узнать оператором #.
Пары ключь-значение только считать.

next() — выглядит как более короткий хак, чем с pairs. И не решает проблему если нужен именно размер, а не проверка на пустоту. Размер «массива» тут не в тему.


PS: Размер таблицы‐массива узнаётся за O(log(table_size)) (O(table_size), если размер таблицы больше MAX_INT/2 или таблица специальным образом построена) в lua. Не знаю, что в luajit (но тесты показывают, что чтобы там ни было, оно не даёт O(1)), но в lua-5.3.4 используется бинарный поиск; в лучшем случае бинарный поиск по массиву, в худшем — по хэшу. Они как‐то ухитряются делать это быстро (скорее всего, мои тесты просто все прошли как бинарный поиск по массиву), но идея мне всё равно не нравится.

Можно считать ключи во время записи значения через метатаблицы. И соответственно отдавать это количество.

Они (бразильцы) из вредности на luajit не рассчитывают. Поставил IupLua (бразильский пакет для рисования окошек с кнопками) — не работает с LuaJIT. Так и этак — всё равно не работает. Пошёл на форум LuaJIT, там сказали: переименуйте lua51.dll в lua5.1.dll! Переименовал — заработало (правда, такая фигня, что немедленно удалил). Основной недостаток Lua — всё приходится делать самому, нет ничего готового. Хочешь рисовать — оберни OpenGL! Правда, обёртывать легко, опять же за счёт LuaJIT.
Я писал диплом на функциональном языке (GARF) в 84-м году, затем изучал лямбда-исчисление, категории и монады как математик. Последнее время по необходимости стал программировать и из всех языков мне с большим отрывом нравится Lua. А я понимаю глубокую суть вещей! Вот песня про Lua на бразильском языке
youtu.be/NxzP1XPCGJE
Tarde uma nuvem rsea lenta e transparente.
Sobre o espao, sonhadora e bela!
Surge no infinito a Lua docemente,
Enfeitando a tarde, qual meiga donzela
Que se apresta e a linda sonhadoramente,
Em anseios d'alma para ficar bela
Grita ao cu e a terra toda a Natureza!
Cala a passarada aos seus tristes queixumes
E reflete o mar toda a Sua riqueza…
Suave a luz da Lua desperta agora
A cruel saudade que ri e chora!
Tarde uma nuvem rsea lenta e transparente
Sobre o espao, sonhadora e bela!

Что значит «светит Lua в темноте»
у меня есть свитер, с логотипом Lua, созданный по спецзаказу моей женой специально для меня и Луа мне то же светит в темноте)
Итераторы и метатаблицы. А чего нет (например, массивов и структур), то теперь есть за счёт LuaJIT (компилятор, позволяющий в программе на Lua определять структуры данных на C)

Да, сравнение с JS напрашивается. Что нравится лично мне:


  1. Прототипная модель на порядок проще. Без дуристики с функциями-конструкторами, Object.create и т.п. Просто создаётся таблица и назначается мета-таблицей нового объекта.
  2. Сильно меньше неявных преобразований непонятно откуда непонятно во что. Если бы отключить неявное преобразование между строками и числами — было бы совсем хорошо.
  3. Значительно проще правила сравнения и истинности. Без феерического идиотизма ==/===. Заодно — отсутствие дуализма null/undefined.
  4. На порядок проще embedding API. Сравниваю по опыту написания нативных аддонов к Node.JS.

Мой личный вывод: в JS накрутили какой-то дикой, неочевидной логики, которая только усложняет жизнь. Особенно много веществ употребили, когда делали реализацию прототипного ООП.

помню аддоны и какие-то время макросы для World of Warcraft можно было писать на Lua :)
Скрипты для Nmap можно писать на Lua.

не ну скрипты много где, в nginx тоже можно

Когда привыкаешь к итераторам, других циклов уже писать не хочется. Прототипное наследование (метатаблицы) гораздо удобнее ООП. Ну и по мелочам хорошо, начиная с одновременного присваивания. Изумительная обработка регулярных выражений. Поскольку Lua замышлялся как небольшой встроенный язык, полную обработку регулярных выражений туда не вставили (места мало). Зато есть команда, позволяющая найти что-то по шаблону, применить к найденному произвольную функцию и результат подставить вместо. Сейчас Lua перерос исходный замысел, компилятор LuaJIT выдаёт программы, по скорости мало с чем сравнимые
blog.carlesmateo.com/2014/10/13/performance-of-several-languages
плюс позволяет использовать любые структуры данных C.
С яваскриптом сравнивать смешно, он написан за один вечер (как хвастался его создатель), а потом нарастал по принципу кучи компоста (хи-хи, за это мне снизили карму фанаты яваскрипта).

Немного непоследовательное написание:


  1. Комментарии
  2. Переменные
  3. 15 minutes later
  4. компоновка сцены
  5. условные операторы.
Sign up to leave a comment.

Articles