Comments 75
function condition()
return true
end
print(condition() and false or true)
Happy debugging.
print(not condition())
Это ещё можно решить:
print(not condition() and true or false)
А вот это?
print(condition() and nil or false)
По идее, всегда false
выведет, потому что nil
приравнивается к false
, а значит "... and nil
" всегда false
.
Всё верно. Задача в том чтобы минимально переделать это выражение так чтобы в зависимости от condition возвращалось nil или false.
а с небольшим оверхедом (за счет читаемости, скорости работы и чутка памяти) это задачу можно решить так:
print( ({[true]=false})[not condition() or false] )
В нашем понимании идеальный скриптовый язык должен быть динамическим.Почему? Динамически типизированный код на порядок хуже поддается оптимизации, а в играх (особенно под мобильные устройства не последних поколений) это может быть заметно.
У того же AngelScript типизация как раз строгая, и в некоторых обсуждениях ему её ставять в недостаток, мол, в скриптовом языке такое не нужно.
Часто сталкиваюсь со предубеждением, что «статическая типизация» требует избыточных аннотаций и замусоривает код. Ради красоты кода в жертву приносятся скорость исполнения, качество автокомплита, статические проверки и прочие важные вещи. Однако с помощью вывода типов даже в языках с сильной статической типизацией может быть очень легковесный синтаксис: достаточно взглянуть на F#, Crystal, Nim и множество других примеров.
Но вот устойчивость к ошибками при использовании статической типизации значительно выше, что позволило бы использовать менее опытных программистов. Очень жаль, что статической типизации так боятся.
У Lua, на мой взгляд, есть ещё одно преимущество. С помощью luaL_newstate()
наплодить только независимых интерпретаторов Lua со всем окружением, сколько нужно. В итоге у вас может быть один интерпретатор, который обрабатывает скрипты пользователя, и другой, который скриптует UI, и они никак друг на друга не влияют и никак друг о друге не знают.
Lua предназначен для C а не для С++
Ну это как-бы надумано. API биндинга на C, но это не значит что этот API невозможно удобно завернуть для C++ практически с 0-выми издержками. Есть очень хорошая биндинговая либа sol2 (C++14). А вообще биндить Lua совсем не сложно.
Lua — это медленно
Lua интерпретатор, наверное да. А LuaJIT по скорости мало уступает коду сгенерированному из C.
Критикуя Lua, говорят о том, что язык это древний, что он, что называется, «из коробки», не поддерживает ООП
Странно об этом слышать, когда в документации, ООП возможности хорошо рассматриваются.
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.
т.е. интерпретировать можно только то что уже есть в пакете приложения.
Само встраивание простое, но интерпретатор в отличии от Lua или V8 не имеет отдельного стейт-хендлера, т.е. более одного интерпретатора в код не внедришь (не всем это кстати нужно). Python большой и медленный (относительно Lua), порог вхождения выше.
В "танках" вроде питон всторен, если не ошибаюсь.
Большой — вероятно, но как я ответил в коменте, легко обрезается, так же «большой» может быть преимуществом перед «маленьким» lua, когда ситуация требует нечто больше возможности прокинуть куски с с++ и как то заскриптовать их.
Скорость — так себе аргумент, даже относительно luajit. Обычно в скрипты выносят простую логику, а не сложные вычисления, так что даже на самом медленном языке надо постараться, что бы значительно увеличить нагрузку на cpu или время кадра.
Порог вхождения — для кого? Для тех, кто будет писать скрипты, или тех, кто будет встраивать язык в основное приложение? Для первых — если эта группа людей не знает ни питон, ни lua, выучить базовый синтаксис любого языка будет просто; + python более популярен(человека разбирающегося по минимуму в python найти в сто раз проще); учить api, предоставляемое основной программой учить придется в любом случае. Для вторых — не очень знаком с lua, но не думаю что объем кода биндингов будет сильно отличатся, но я практически уверен, что для lua существуют инструменты для значительного упрощения процесса биндинга(для python существует).
Не подумайте, что я топлю за python в каждом приложении где нужен скриптинг. Просто статья по смыслу выглядит для меня так — «нам нужны скрипты, мы тут полазили, посмотрели, что то нам ничего не подошло, а почему? А потому что нам понравился lua, посмотрите какой он как будто бы и плохой, но по настоящему он очень хороший. Мы даже свою IDE для него написали. Всем рекомендуем.»
Все аргументы против других языков вообще не выглядят убедительно, и как будто бы приведены для того, что бы оправдать выбор lua; реального сравнения нет, и часть про другие языки вообще лишней кажется.
К основной части по lua претензий почти нет, кроме одной — где конкретный ответ на вопрос «почему lua?», а не другой ЯП в контексте сравнения с другими языками(а его нет, потому что сравнения то и не было :))?
[x for x in ().__class__.__base__.__subclasses__() if x.__name__ == 'Popen'][0]('calc.exe')
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 namespacelwn.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
, он кешируется откомпилированным, и второй раз он не компилируется, даже если подключить его ещё раз. Этот байткод даже можно получить как миссив байт и куда-нибудь сохранить. Другое дело, что вроде как он может отличаться на разных платформах, поэтому компилировать его заранее и распространять уже в байткоде чревато возможными проблемами.
Плюс редактировать удобно. Могу представить себе тулинг в котором вы висите на условном бряке, и редактируете следующую строчку, отпускаете бряк и оно полетело дальше без каких либо приседаний.
То что он написан на С позволяет собрать его под любую платформу.
А что со www.squirrel-lang.org не так?
В реальности же придётся выбирать из двух подобных проектов — V8 и WebKit. И тот и другой имеют достаточно большие размеры
А как же Duktape или JerryScript, да и вообще можно здесь покопаться еще List of ECMAScript engines
Однако изучить его как следует уже не так-то просто. Как результат, хорошие Python-программисты встречаются редко и дорого стоят.
Вот тут не соглашусь. Пусть и всякие сложные питоновские выкрутасы, которые позволяют писать код понятнее и короче, или всякую интроспекцию делать, или еще что-нибудь, но самая база в нем максимально простая, что ее можно выучить за час. Наверное, самый простой в освоении язык, что я знаю.
Python, наверное, самый простой в освоении язык, что я знаю.
если так, то вы видимо не знаете Lua. проще языка я не встречал.
более того, я смог за пару вечеров освоить синтаксис С (после Java) и некоторые стандартные функции и писать на нем более-менее работающий код, а с питоном не смог, ибо слишком уж много сахара в питоне, который нужно знать (чтобы уметь прочитать чужой код).
если API сделано реально хорошо, то можно писать и в императивном стиле (без использования ООП явного или неявного). примеры: медиа-библиотека allegro5 для C, игровой движок Love2D (Lua). там действительно хорошие API, название и действие функций если не знаешь, можно просто угадать.
просто есть скриптовые языки, в которых из коробки идут всякие возможности функциональных языков, явная поддержка ООП, только зачем это всё, если это всё не используется? ну или если надо, то можно реализовать через другие средства языка. в Lua это так. там есть минимум для реализации всего, что нужно. в Python напичкано всё подряд под предлогом «если тебе это не надо — не используй»
И тут уже критерии выбора могут быть другие — что lua может привнести в наш скриптовый мир, а что может принести другие языки(я имею в виду стандартную библиотеку языков, хоть api и решает, но иногда скриптовые языки впиливают не для программирования логики, а для расширения программы)? Сколько понадобится времени на поиск человека, который будет знать python + выучит наш api, и то же самое для lua, или js(по своему кругу общения не знаю никого кто бы писал на lua)?
пс: в частности про python, он не новомодный, в девяностых, кажется, начал разрабатыватся :)
выучить Python — нифига не пара часов. основной синтаксис да, можно поднатаскать. но ох уж эти значащие отступы…
новомодность языка: это про то, что в него добавляют кучу всяких плюшек, которые изобретают/улучшают в новое время, а не когда-то давно.
Python старше Lua. но реализовать Lua в том виде, в котором он есть сейчас, можно было лет на 30 раньше. с Python такое не прокатило бы (наверное, я не то чтобы сильно компетентен в вопросах, связанных с Python)
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>
ну все, держите меня семеро!
Если нам, для построения игрового движка, нужен какой-нибудь интерпретатор языка — мы можем найти множество таких интерпретаторов. В реальности же придётся выбирать из двух подобных проектов — V8 и WebKitКлассно.
Haxe, по сути, является не столько языком, сколько транс-компилятором в другие языки. А это не то, что нам нужно.
Кроме поддержки компиляции в натив через c++, под haxe с первого релиза была своя vm для байткода — neko
На смену ей сейчас пришел hashlink.haxe.org
Как использовать github.com/HaxeFoundation/hashlink/wiki/Embedding-HashLink
Хотя как по мне перспективнее всего встраивать js, так как в npm можно найти библиотеку для решения практически любой задачи.
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.
Встраиваемые языки: почему Lua?