Информация

Дата основания
2010
Местоположение
Россия
Сайт
www.socialquantum.ru
Численность
201–500 человек
Дата регистрации

Блог на Хабре

Обновить
Комментарии 74
Тернарный оператор в Lua и не нужен. (cond? true_val: false_val) в Lua выглядит так: (cond and true_val or false_val)
А если cond == true и true_val вычисляется в false, код, вычисляющий false_val будет выполнен?
Будет выполнен и всё выражение будет равно его значению, вне зависимости от возврата false_val. Отличный способ сделать себе неочевидную проблему. Но, надо заметить, в lua не так много значений тождественны false: это сам false и nil. Всё остальное тождественно true.
function condition()
   return true
end

print(condition() and false or true)

Happy debugging.
Как это отменяет тот факт, что and-or идиома — это не тернарное условие? :)
Никак :)

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

Это ещё можно решить:


print(not condition() and true or false)

А вот это?


print(condition() and nil or false)

По идее, всегда false выведет, потому что nil приравнивается к false, а значит "... and nil" всегда false.

Всё верно. Задача в том чтобы минимально переделать это выражение так чтобы в зависимости от condition возвращалось nil или false.

интересно посмотреть на задачу, где нужно различать nil и false. это, кажется, не самое полезное занятие (кроме случаев, когда куда-то был явно записан false, но там можно сделать проверку на равенство).

а с небольшим оверхедом (за счет читаемости, скорости работы и чутка памяти) это задачу можно решить так:
print( ({[true]=false})[not condition() or false] )
что-то со мной было не то. 'or false', конечно, не надо
print( ({[true]=false})[not condition()] )
В нашем понимании идеальный скриптовый язык должен быть динамическим.
Почему? Динамически типизированный код на порядок хуже поддается оптимизации, а в играх (особенно под мобильные устройства не последних поколений) это может быть заметно.

У того же AngelScript типизация как раз строгая, и в некоторых обсуждениях ему её ставять в недостаток, мол, в скриптовом языке такое не нужно.

AngelScript многократно медленнее LuaJIT. По крайней мере год назад так было.

А я не говорю, что он лучше, я лишь о том, что скриптовые языки со строгой статической типизацией существуют.

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

Часто сталкиваюсь со предубеждением, что «статическая типизация» требует избыточных аннотаций и замусоривает код. Ради красоты кода в жертву приносятся скорость исполнения, качество автокомплита, статические проверки и прочие важные вещи. Однако с помощью вывода типов даже в языках с сильной статической типизацией может быть очень легковесный синтаксис: достаточно взглянуть на F#, Crystal, Nim и множество других примеров.
В любой программе, в том числе и в играх, много некритичного к производительности кода, который не имеет смысла оптимизировать.
Но вот устойчивость к ошибками при использовании статической типизации значительно выше, что позволило бы использовать менее опытных программистов. Очень жаль, что статической типизации так боятся.
Дело не только в оптимизации, они не поддаются средствам статического анализа: страдает качество кода, страдает автокомплит, стоимость разработки увеличивается из-за этого.

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

У Lua, на мой взгляд, есть ещё одно преимущество. С помощью luaL_newstate() наплодить только независимых интерпретаторов Lua со всем окружением, сколько нужно. В итоге у вас может быть один интерпретатор, который обрабатывает скрипты пользователя, и другой, который скриптует UI, и они никак друг на друга не влияют и никак друг о друге не знают.

Lua предназначен для C а не для С++

Ну это как-бы надумано. API биндинга на C, но это не значит что этот API невозможно удобно завернуть для C++ практически с 0-выми издержками. Есть очень хорошая биндинговая либа sol2 (C++14). А вообще биндить Lua совсем не сложно.


Lua — это медленно

Lua интерпретатор, наверное да. А LuaJIT по скорости мало уступает коду сгенерированному из C.


Критикуя Lua, говорят о том, что язык это древний, что он, что называется, «из коробки», не поддерживает ООП

Странно об этом слышать, когда в документации, ООП возможности хорошо рассматриваются.


Даже множественное наследование возможно.

От программистов на С/С++ вообще странно слышать про «древний язык»
Поправьте, если ошибаюсь, но ведь при выборе скриптового языка для игр Lua уже очень много лет вариант по умолчанию…
Lua — лучший выбор, но при этом вы написали свою IDE, чтобы иметь возможность писать на нем с хоть минимальным комфортом? Неплохо, неплохо.
Эм точно? А то пишут у нас свое. Не EmmyLUA как-то слабо похоже.
А JIT внезапно стал возможен на ios? Насколько я помню, ios запрещает ставить флаг исполняемости на data сегментах памяти.
Так оно же не напрямую выполняется, а интерпретируется самой игрой. Примерно как аудио декодируется и стримится в аудиовывод также и скрипт гоняет некоторую логику. Так что 755 там и не нужен.

"не напрямую выполняется, а интерпретируется" — это уже не JIT.

Парсится lua-файл и перегоняется в специфичный байт-код, то бишь jit-ится. Дальше происходит побайтовая интерпретация команд этого байт-кода на условной lua-vm.
В общем lua на ios точно есть и вполне себе работает в составе игр.

Нет, речь судя по всему шла про LuaJIT, разновидность Lua с JIT в привычном смысле: код на Lua "перегоняется" не в байткод, а машинный для текущей платформы.

Нет, слово «jit-ится» означает не то что вы назвали.
Запрет iOS на испольнение не технический, а юридический.

dev.hel.fi/paatokset/media/att/9a/9aa5692b91f2b538eeb352c425b3e66c09e6b1a5.pdf

3.3.2
Except as set forth in the next paragraph, an Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exceptions to the foregoing are scripts and code downloaded and run by Apple's built-in WebKit framework or JavascriptCore, provided that such scripts and code do not change the primary purpose of the
Application by providing features or functionality that are inconsistent with the intended and
advertised purpose of the Application as submitted to the App Store.


т.е. интерпретировать можно только то что уже есть в пакете приложения.
По крайней мере во времена 2.0.4 JIT-часть была отрублена для iOS, сейчас вряд ли что-то поменялось. Но там и сам интерпретатор быстрее, чем в ванильной луа.

Edit: нет, в голове тоже выключено.
Интересно, что не так с python? Почему система библиотек неконсистентная? В чем проблема встраивания в с\с++?

Само встраивание простое, но интерпретатор в отличии от Lua или V8 не имеет отдельного стейт-хендлера, т.е. более одного интерпретатора в код не внедришь (не всем это кстати нужно). Python большой и медленный (относительно Lua), порог вхождения выше.


В "танках" вроде питон всторен, если не ошибаюсь.

ИМХО, единое состояние на приложение — это единственный аргумент, но как вы упомянули, и то всегда :).

Большой — вероятно, но как я ответил в коменте, легко обрезается, так же «большой» может быть преимуществом перед «маленьким» lua, когда ситуация требует нечто больше возможности прокинуть куски с с++ и как то заскриптовать их.

Скорость — так себе аргумент, даже относительно luajit. Обычно в скрипты выносят простую логику, а не сложные вычисления, так что даже на самом медленном языке надо постараться, что бы значительно увеличить нагрузку на cpu или время кадра.

Порог вхождения — для кого? Для тех, кто будет писать скрипты, или тех, кто будет встраивать язык в основное приложение? Для первых — если эта группа людей не знает ни питон, ни lua, выучить базовый синтаксис любого языка будет просто; + python более популярен(человека разбирающегося по минимуму в python найти в сто раз проще); учить api, предоставляемое основной программой учить придется в любом случае. Для вторых — не очень знаком с lua, но не думаю что объем кода биндингов будет сильно отличатся, но я практически уверен, что для lua существуют инструменты для значительного упрощения процесса биндинга(для python существует).

Не подумайте, что я топлю за python в каждом приложении где нужен скриптинг. Просто статья по смыслу выглядит для меня так — «нам нужны скрипты, мы тут полазили, посмотрели, что то нам ничего не подошло, а почему? А потому что нам понравился lua, посмотрите какой он как будто бы и плохой, но по настоящему он очень хороший. Мы даже свою IDE для него написали. Всем рекомендуем.»
Все аргументы против других языков вообще не выглядят убедительно, и как будто бы приведены для того, что бы оправдать выбор lua; реального сравнения нет, и часть про другие языки вообще лишней кажется.
К основной части по lua претензий почти нет, кроме одной — где конкретный ответ на вопрос «почему lua?», а не другой ЯП в контексте сравнения с другими языками(а его нет, потому что сравнения то и не было :))?
Я не автор статьи. Вы не туда зпостили. Думаю им действительно просто понравился Lua.
Ну это только последняя часть не к вам(и даже не думал писать с претензией конкретно к вам). Это я просто резюмировал свое отношение.
Чересчур мощная интроспекция — python невозможно посадить в песочницу. Конечно, зависит от задачи, но в игровых скриптах возможность делать что-то такое мне видится нежелательной:

[x for x in ().__class__.__base__.__subclasses__() if x.__name__ == 'Popen'][0]('calc.exe')
python относительно легко «кастрируется», и всякие Popen и компанию можно легко вырезать, оставив безобидный сабсет функций, необходимый для скриптинга. Но это требует определенных знаний и времени. Собственно, как и реализация необходимого функционала для Lua. Так что тут зависит от ситуации, что кому нужно.
python относительно легко «кастрируется»
Вот уж нет, совершенно точно не «легко». 10 лет назад один дядька сделал штуку, которая по задумке должна была закрывать возможность писать в файлы (github.com/tav/scripts/blob/master/safelite.py)
и попросил найти в ней уязвимости. Конец немного предсказуем: tav.espians.com/a-challenge-to-break-python-security.html

Ещё были попытки у pysandbox, но там также признали поражение:
so many restrictions have needed to be added, pysandbox cannot be used for anything «more complex than evaluating '1+(2*3)'». Basic language constructs like «del dict[key]» have been removed because they can be used to modify __builtins__ and break out of the restricted namespace
lwn.net/Articles/574215
lwn.net/Articles/574323
nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

В стандартной библиотеке был модуль rexec, но он также признан опасным и удалён в 3 версии
docs.python.org/2/library/rexec.html

PyPy пытались, но их sandbox «is not actively maintained. You will likely have to fix some issues yourself».

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

Поясните, пожалуйста, за интерпретируемость. В чём вообще смысл делать встраиваемые в игру языки интерпретируемыми? Игра ведь не сайт, она не должна грузиться за доли секунды, можно без проблем успеть скомпилировать и соптимизировать с -О3 все скрипты по ходу дела, может даже в отдельном треде, даже если они только что скачаны, а если не скачаны — то тем более, можно просто закэшировать результат компиляции(?) REPL для внутриигровой дебажной консольки вроде тоже ничему не противоречит(?)


Дело в безопасности — произвольный бинарь сложнее контролировать? Дело просто в том что все компилируемые языки сложны? Будет ли полезен новый язык с такими свойствами — простой, контролируемый, легко встраиваемый, как lua, но при этом компилируемый? Или, может быть, ограниченная версия lua с чуть меньшей рефлексией но с компилируемостью?

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

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

Вообще, в Lua так и происходит, сначала работает компилятор в байтокд, а затем этот байткод выполняется. Когда импортируется модуль через require, он кешируется откомпилированным, и второй раз он не компилируется, даже если подключить его ещё раз. Этот байткод даже можно получить как миссив байт и куда-нибудь сохранить. Другое дело, что вроде как он может отличаться на разных платформах, поэтому компилировать его заранее и распространять уже в байткоде чревато возможными проблемами.

Моды для iOS игр? Ну, не знаю)
на iOS/UWP не будет работать JIT (нельзя W и X одновременно на странице памяти).
Плюс редактировать удобно. Могу представить себе тулинг в котором вы висите на условном бряке, и редактируете следующую строчку, отпускаете бряк и оно полетело дальше без каких либо приседаний.
У lua есть еще одно достоинство он маленький порядка 200кб.
То что он написан на С позволяет собрать его под любую платформу.
А что со www.squirrel-lang.org не так?
А Lisp-подобные языки вы не рассматривали?
В реальности же придётся выбирать из двух подобных проектов — V8 и WebKit. И тот и другой имеют достаточно большие размеры

А как же Duktape или JerryScript, да и вообще можно здесь покопаться еще List of ECMAScript engines

Однако изучить его как следует уже не так-то просто. Как результат, хорошие Python-программисты встречаются редко и дорого стоят.

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

Python, наверное, самый простой в освоении язык, что я знаю.

если так, то вы видимо не знаете Lua. проще языка я не встречал.
более того, я смог за пару вечеров освоить синтаксис С (после Java) и некоторые стандартные функции и писать на нем более-менее работающий код, а с питоном не смог, ибо слишком уж много сахара в питоне, который нужно знать (чтобы уметь прочитать чужой код).
А для скриптинга логики вы будете использовать кучу сахара и магию? Ведь не обязательно использовать все, что предоставляет язык, и скрипты в 99% случаев будут представлять подергивание api, предоставленного основным приложением. Если api простое — то не важно на чем его использовать, хоть на ассемблере. Если сложное — куча сахара это даже в плюс, так как с большой вероятностью поможет упростить api. Ведь в 100% случаев скрипты предоставляют свою собственную инфраструктуру, и магического от языка там ничего не останется, только магия за самим api, предоставляемого скриптам. Что вы думаете по этому поводу?
полностью согласен про API. но из этого вытекает вопрос: а зачем нужны все эти свистоперделки новомодных языков, если для скрипта достаточно нескольких базовых функций языка? остальное держится на API.
если API сделано реально хорошо, то можно писать и в императивном стиле (без использования ООП явного или неявного). примеры: медиа-библиотека allegro5 для C, игровой движок Love2D (Lua). там действительно хорошие API, название и действие функций если не знаешь, можно просто угадать.

просто есть скриптовые языки, в которых из коробки идут всякие возможности функциональных языков, явная поддержка ООП, только зачем это всё, если это всё не используется? ну или если надо, то можно реализовать через другие средства языка. в Lua это так. там есть минимум для реализации всего, что нужно. в Python напичкано всё подряд под предлогом «если тебе это не надо — не используй»
Я просто склоняюсь к мысли, что вообще не важно какой язык, lua, python, js, любую другую хрень можно прикрутить, основную роль будет играть api.

И тут уже критерии выбора могут быть другие — что lua может привнести в наш скриптовый мир, а что может принести другие языки(я имею в виду стандартную библиотеку языков, хоть api и решает, но иногда скриптовые языки впиливают не для программирования логики, а для расширения программы)? Сколько понадобится времени на поиск человека, который будет знать python + выучит наш api, и то же самое для lua, или js(по своему кругу общения не знаю никого кто бы писал на lua)?

пс: в частности про python, он не новомодный, в девяностых, кажется, начал разрабатыватся :)
выучить Lua — пара часов. выучить API — по времени это занимает почти всё, что отведено на вхождение в проект.
выучить Python — нифига не пара часов. основной синтаксис да, можно поднатаскать. но ох уж эти значащие отступы…

новомодность языка: это про то, что в него добавляют кучу всяких плюшек, которые изобретают/улучшают в новое время, а не когда-то давно.
Python старше Lua. но реализовать Lua в том виде, в котором он есть сейчас, можно было лет на 30 раньше. с Python такое не прокатило бы (наверное, я не то чтобы сильно компетентен в вопросах, связанных с Python)
Совсем забыл — есть ориентированный на встраивание язык TCL. Он древний, но вполне качественный. По эффективности — видел даже реализацию на JavaME.
Спасибо. Понял, что главный аргумент — удобство встраивания языка в свой проект.
О боже, есть даже Lua для JS в HTML! )
lua.vm.js

<script src="lua.vm.js"></script>

<script type="text/lua">
js.global:alert('hello from Lua script tag in HTML!') -- this is Lua!
</script>


ну все, держите меня семеро!
Осталось прикрутить WebAssembly в качестве бекенда для LuaJIT — тогда уже ничто не удержит.
Если нам, для построения игрового движка, нужен какой-нибудь интерпретатор языка — мы можем найти множество таких интерпретаторов. В реальности же придётся выбирать из двух подобных проектов — V8 и WebKit
Классно.
Haxe, по сути, является не столько языком, сколько транс-компилятором в другие языки. А это не то, что нам нужно.

Кроме поддержки компиляции в натив через c++, под haxe с первого релиза была своя vm для байткода — neko
На смену ей сейчас пришел hashlink.haxe.org
Как использовать github.com/HaxeFoundation/hashlink/wiki/Embedding-HashLink

Хотя как по мне перспективнее всего встраивать js, так как в npm можно найти библиотеку для решения практически любой задачи.
В аргументации относительно скорости Lua вы незаслуженно обошли библиотеку FFI в LuaJIT, которая позволят выжать ещё больше скорости в критических местах и сильно упрощает использование C API внутри скриптов.

У Lua есть одна проблема — версии 5.1, 5.2 и 5.3 между собой несовместимы ну просто никак. OpenResty работает на 5.1 и переходить не собирается.
У Lua есть одно преимущество — язык реализует только то, что описано в стандарте С. Даже работы с файлами там нет. Всё остальное — через библиотеки. Как и C. Аналога libc на Lua правда нет.
Ну и самое главное — это офигенный, сногсшибательный, гениальный дизайн, в котором всё направлено на удобство встраиваемости. Вот тут автор языка про это коротко рассказывает: https://queue.acm.org/detail.cfm?id=1983083

5.1 и 5.2 между собой совместимы (в 5.2 некоторые методы работы с таблицами депрецированные в 5.1 ещё не удалены, а в 5.3 уже удалены).


Вот тут разница. В синтаксисе языка только добавления. Естественно код 5.2 с метаметодами в 5.1 работать не будет. Но код 5.1 будет работать в 5.2.


A LuaJIT поддерживает диалекты 5.1/5.2. OpenResty нормально работает на LuaJIT-2.0.4/2.0.5 с поддержкой диалектов 5.1/5.2.


Интересно, кому нужен Lua 5.3, без поддержки этого диалекта LuaJIT-ом?

Дело в том, что для наших целей нам часто нужны управляющие конструкции — ветвление и циклы, в то время как XML это декларативное описание.


Есть такая прекрасная вещь — рекурсия с терминальной ветвью.
Но видимо, чтобы понять рекурсию, нужно понять рекурсию.

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