LINUX.ORG.RU

Luau - Lua с «батарейками», написанный на C++17

 ,


2

5

Luau (GitHub) - встраиваемый, Lua 5.1-совместимый (и частично с Lua 5.2-5.4), язык со следующими улучшениями (или «улучшениями»?):

function foo(x: number, y: string): boolean
    local k: string = y:rep(x)
    return k == "a"
end
type Point = { x: number, y: number }
type Array<T> = { [number]: T }
type Something = typeof(string.gmatch("", "%d"))
for k, v in {1, 4, 9} do
    assert(k * k == v)
end
  • улучшенный repl (используется C-альтернатива readline Isocline)
  • и другие изменения ;)

По соображениям безопасности отсутствуют io, os, package и debug.

(En|Destr)oy!

★★★★★

Последнее исправление: dataman (всего исправлений: 2)

Составные операторы это конечно плюс. Но по остальному стоило ли делать форк языка? Хз даже.

Roblox

Аааа, понятно, они для себя и тех кто там миниигры клепает. Тада ладна.

Лучше бы luajit дофигачили до последней официальной lua. Все бы ручками хлопали и попками вертели

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)

type Array = { [number]: T }

Когда плюсовик влез в другой язык гыгыгыгыгы. Нахер, фтопку

LINUX-ORG-RU ★★★★★
()

мне в lua не хватало u16string и regexp над ними, чтото велосипедил, где то у меня на lua валяется недоделанный редактор студия для андроид

anonymous2 ★★★★★
()

Мои бенчмарки (из LuaJit):

ФайлLua 5.4LuauLuaJit 2.1LuaJit OpenResty 2.1Ravi
nbody.lua0m0.004s0m0.002s0m0.002s0m0.002s0m0.004s
binary-trees0m0.003s0m0.002s0m0.003s0m0.004s0m0.003s
nsieve0m0.005s0m0.002s0m0.002s0m0.003s0m0.005s
scimark-sparse0m18.234s0m16.098s0m3.081s0m3.015s0m17.129s
dataman ★★★★★
() автор топика
Ответ на: комментарий от anonymous2

Да, спасибо им. Но даже в их стандартной библиотеке по старинке используется lua.h. В дискуссиях я их спросил, можно ли (и как) использовать С++ API. Посмотрим, что ответят.

dataman ★★★★★
() автор топика
Ответ на: комментарий от dataman

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

yoghurt ★★★★★
()
Ответ на: комментарий от Psilocybe

Ну извините, что отнёс циклы/операторы и т.д. к «батарейкам».

dataman ★★★★★
() автор топика

Вроде как Lua и так используется как встраиваемый язык. А это еще более встраиваемый получается.

Psilocybe ★★★★
()
Ответ на: комментарий от Vlad-76

Пробовал скомпилировать Терру и так и сяк, но никакой цветок не выходит. Забил.

dataman ★★★★★
() автор топика
Ответ на: комментарий от Psilocybe

к тому же так себе встраиваемый, ибо не C-ABI

AKonia ★★
()
Ответ на: комментарий от annerleen

а как без io получить доступ к фс?

Перенести код из Lua.io к себе.

чем это лучше ravi?

Хотя бы тем, что на C++. :)

dataman ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Язык создан как встраиваемый

И встраивают его теперь по поводу и без.

Поэтому «убогонький недоязычок» тут не к месту.

К месту. Одно другому не противоречит.

pr849
()
Ответ на: комментарий от dataman

Посмотрим, что ответят.

Предлагают использовать LuaBridge3, поддерживающую Luau.

dataman ★★★★★
() автор топика
Ответ на: комментарий от dataman

0m0.004s

На таких коротких интервалах никто не бенчмаркает.

slovazap ★★★★★
()
Ответ на: комментарий от intelfx

для этого уже есть тэг, причем не один. Например rust.

bonta ★★★★★
()
23 ноября 2022 г.

…cпустя некоторое время: добавлен JIT (компилировать с опцией -DLUAU_NATIVE=ON).

Для теста я выбрал scimark-fft.lua.

Lua enginerealusersys
lua 5.4.50m40.937s0m40.915s0m0.000s
luajit0m3.402s0m3.365s0m0.000s
luau0m35.659s0m35.563s0m0.004s
luau –codegen0m18.207s0m18.199s0m0.008s
dataman ★★★★★
() автор топика

Начинается. Один язык был, который не надо переизучать каждый месяц потому что они его «совершенству ют» постоянно. Уж лучше я буду а = а + 1 писать

Щас разведут зоопарк

pihter ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Лучше бы luajit дофигачили до последней официальной lua. Все бы ручками хлопали и попками вертели

Два чая этому Дрону!

pihter ★★★★★
()
Ответ на: комментарий от dataman

Потребление памяти можешь оценить?

Stil ★★★★★
()
9 ноября 2023 г.
  • код переехал на https://github.com/luau-lang/luau;
  • удалена опция для компиляции с поддержкой генерации нативного кода – теперь она есть «из коробки» с ключом --codegen.

Новости: https://luau-lang.org/news

dataman ★★★★★
() автор топика
Последнее исправление: dataman (всего исправлений: 1)
Ответ на: комментарий от dataman

Добавлю, что LuaBridge3 поддерживает Luau «из коробки».

dataman ★★★★★
() автор топика

вот непонятно, зачем в луе для локальной переменной писать local, хотя она должна быть локальной по дефолту. а глобальная - global.

alysnix ★★★
()
Ответ на: комментарий от frunobulax

…«j» пропало, что осталось на трубе?

dataman ★★★★★
() автор топика
Ответ на: комментарий от alysnix

вот непонятно, зачем в луе для локальной переменной писать local

Чтобы ехал local через function. А иначе будет слишком мало слов в программе.

bread
()
Ответ на: комментарий от alysnix

У этого есть свои преимущества и это обычное поведение для большинства языков. Локальность по умолчанию только звучит хорошо, но на деле она сразу обязывает на просто написать print("hello") а ещё внести в локальную область этот самый print в lua стандартная база из коробки вшита в саму луа, её не надо подгружать и объявлять, она не иммутабельна и может быть изменена динамически или ещё до старта работы это следствие того что луа не существует сама по себе это всегда встраиваемый язык. Есть ещё разница в том как хранятся локальные и глобальные данные. Локальные быстрые ибо они переносятся на стек целиком либо прямым указателем без взятия хеша с глобальной таблички каждый раз при обращении. Поэтому есть ограничение на локальные переменные и функции. Отдельное слово global для явного указания что данные глобальны тоже лишь звучит красиво, а на деле костылей и подпорок не оберёшься из за побочных эффектов.

Идеального варианта нет, но явное указание локальности и «по умолчанию» глобальность дают хороший компромисс и большую гибкость, когда ты одновременно контролируешь и эффективное использование памяти и вычислительных ресурсов в зависимости в том что тебе более важно области видимости do...end никто не отменял как и в си {...} и в десяках других языков, опять же в них же всё всегда тоже глобально, а локальность компилируемой/интерпретируемой единицы есть сама по себе и лишь в отдельных случаях ты пишешь типа static int x = 5 если хочешь что-бы даже случайно через export кто не подхватил твои данные и другой компилируемой/интерпретируемой единицы (файла чаще всего, могут быть просто отдельные строки или замыкания или REPL)

Короче на деле не всё так просто и этот момент с local очень хорошо продуман и явно выбран учитывая как особенности языка, так и механизм взаимодействия с ним. У луа, лишь одна фундаментальная проблема это некая особенность работы таблиц и стандартных функций с nil и уже тридцатилетняя привычка людей считать nil ничем это родило кучу всякой фигни с которой нужно просто жить или выпускать lua-6.0 где поведение работы с nil будет изменено или будет новый тип nop который будет не просто типом который не является ни одним из базовых, а просто будет реально ничем, так как сейчас nil и реальное ничто это разные вещи которые вынуждают некоторые штуки в луа просто не делать. local в луа это здорово и хорошо.

Луа это часто просто гениальный баланс компромиссов, там любая закорючка обоснована. Но, некоторые вещи типа nil который тоже коспромисс вызывают спустя 30+ лет вопросы. Тогда это было экономией памяти и это правильно и это сейчас есть и это должно остаться, но вот в неекоторых случаях можно изменить поведение сохранив фичи и внеся ясность, просто тогда это не знали как сделать, а сейчас не делают потому что это будет тотальная несовместимость, просто весь прошлый код сломается разом. Для луа совместимость не так уж и важна в связи со спецификой языка, но тут будет прям конкретное такое эдакое. Так что Вавилонски решится на такое если пойдёт на пенсию наверное, хотяя…

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от Bad_ptr

Местами прикольно

  • циклы новые
  • очень много новых ключевых слов
  • составные операторы (приятно, но не фича)
  • десятка два вообще новых операторов заменяющих функции из math, приятно, но не фича
  • явное ООП (усложнение, class,new, конструкторы, деструкторы)
  • доп фомат вывода значений модное $"Age{number}" вместо конкатенации, но это можно сделать и в ванильке только вместо $ другой символ будет.
  • прикольная вещь с заморозкой таблиц, типа временный const
  • сишный тернарный оператор вместо/в дополнение ... = (...) and x or y

И так далее насколько я посмотрел большинство изменений изменение синтаксиса и сахар, не так то прикольно, там буквально сделали базу типа когда говорят, а чего нет вот этого которое есть в X а почему вот это так, а не как Y :D, без сомнения прикольно, но на главной написано Compatible with Lua 5.4 source & bytecode., а в документации на каждой третей странице The bytecode of this feature is not backwards-compatible with Lua.

Интересная реализация, но пользоваться я этим лично не буду =)

Ну и максимально тупой тест, но жиза. Загрузка и исполнение файла с 1000_000 строк вызова функции складывающей два числа и передающей следующей и так миллион раз. Значения и функция объявлены как локальные конечно.

dron@gnu:~/test$ lua bench.lua 
dron@gnu:~/test$ lua bench.lua 
------- Test 1000000 calls function --------
result:1000000
mem usage KB:83044.077148438
lua 5.1 >>> 77.564 ms
result:1000000
mem usage KB:110259.08691406
lua 5.2 >>> 74.223 ms
result:1000000
mem usage KB:91829.748046875
lua 5.3 >>> 65.794 ms
result:1000000
mem usage KB:77481.393554688
lua 5.4 >>> 52.523 ms
result:1000000
mem usage KB:82460.96484375
lua jit >>> 36.818 ms
result:1000000
mem usage KB:77488.41796875
lua pluto >>> 44.951 ms
dron@gnu:~/test$

Глянул по диагонали исходники, написано что C++ 86.0% C 8.5% ... но по взгляду на код всё должно быть наоборот, где там и зачем c++ непонятно =) Я так понял пилит там всё один человек, клёво, тут прям прицел писать большиие программы, в рамках написания сценариев, однострочников, внешней логики какой программы в целом программулек на +/-250 строчек преимуществ перед любой другой луа, как по мне, нету.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

где там и зачем c++ непонятно

А вот не надо смотреть диагоналями. :)

dataman ★★★★★
() автор топика
Ответ на: комментарий от dataman

Дольше всех собирается. Сразу упало на коде бенча, он же генератор самого себя, начальная lua любая лишь запускает бенч пропуская его один раз, вызывает другую версию луа передавая ему самого себя внутри каждый из них генерирует миллион строк кода, компилит через load() и уже его исполнение бенчится, так что каждая реализация бенчит себя чисто. Эти кульбиты чтобы не держать файл с миллионом строк. Ну так вот luau споткнулась ещё до этапа бенча самой себя а именно на этапе arg[2] == nil для неё пришлось написать ({...})[2] :D, но оно дальше сломалось так как аргументов командной строки оно оказывается не видит аргументами, а пробует исполнить их как файл, которого конечно нету ибо это аргумент для различия бенча как запускалки других бенчей и как бенча… Ну лавввдвнаа, сгенерирую мильён строк и запущу отдельно

dron@gnu:~/test$ du -h bb.lua #сгенерированный файл бенча 18 мегабайт
18M	bb.lua
dron@gnu:~/test$ time ./luau bb.lua 
result:1000000
mem usage KB:24465

real	0m10,507s
user	0m10,167s
sys	0m0,328s
dron@gnu:~/test$ time ./pluto bb.lua 
result:1000000
mem usage KB:24747.8828125

real	0m1,824s
user	0m1,568s
sys	0m0,252s
dron@gnu:~/test$ time lua5.1 bb.lua 
result:1000000
mem usage KB:39090.96875

real	0m0,707s
user	0m0,661s
sys	0m0,040s
dron@gnu:~/test$ time lua5.2 bb.lua 
result:1000000
mem usage KB:39086.662109375

real	0m0,786s
user	0m0,765s
sys	0m0,020s
dron@gnu:~/test$ time lua5.3 bb.lua 
result:1000000
mem usage KB:39087.045898438

real	0m0,647s
user	0m0,607s
sys	0m0,036s
dron@gnu:~/test$ time lua5.4 bb.lua 
result:1000000
mem usage KB:24740.921875

real	0m0,910s
user	0m0,899s
sys	0m0,005s
dron@gnu:~/test$ time luajit bb.lua 
result:1000000
mem usage KB:39098.686523438

real	0m0,578s
user	0m0,517s
sys	0m0,060s
dron@gnu:~/test$ 

А вот с jit они это того самого, перестарались. ибо с --codegen случается

[3424920.241522] traps: luau[2890510] trap invalid opcode ip:55d97f26b816 sp:7ffdaf683ad0 error:0 in luau[55d97f1d4000+185000]

Как хорошо что я ковыряю эмулятор опкодов opemu, с ним видно что

[3425127.307445] OPEMU:  ud2

UD2 опкод это вроде специальный дабы прервать работу программы железно и отпарсить трапсы ядра по этому поводу.

dron@gnu:~/test$ ./luau --codegen bb.lua 
Warning: Native code generation is not supported in current configuration
CodeGen/src/CodeGen.cpp(210): ASSERTION FAILED: isSupported()
Недопустимая инструкция
dron@gnu:~/test$ 

Если я правильно понял, --codegen сейчас по умолчанию в сборке, иначе вроде через ifdef и ключа бы такого не было. Тоесть not supported in current configuration это не конфигурация luau сборки это конфигурация моей машины? Нет всяких SSE4.1+ на которые полагется ихний и егошний :) jit и меня заранее шлют? Короче вот, как то так. Дальше лень копать и выяснять что конкретно не так. luau какая то проблемная для меня, ну вернее я не в курсе её особенностей.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от dataman

-DLUAU_BUILD_TESTS=OFF

Ну это уже почитать надо, а мне лень. И поздно увидел твоё сообщение

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от dataman

Страшно, но оно и не для показа было, на коленке каляк, коляк и всё.


local code_start, code_body, code_end =
[[
    local x,y = 0,1
    local function sum (x,y)
        return x + y
    end
]]
,
[[
    x = sum(x,y);
]],
[[
    print('result:'..x);
    print('mem usage KB:'..collectgarbage("count"))
    return x
]];


function new_stack ()
    return {""}
end

function add_string (stack, s)
    stack[#stack+1] = s;
      for i=#stack-1, 1, -1 do
      if #stack[i] > #stack[i+1] then
          break
      end
      stack[i] = stack[i] .. table.remove(stack);
    end
end
-- luau аргументы не видит
if arg[2] == 'run' then
local code = new_stack();

add_string(code,code_start);
for i = 1, 1000000 do
    add_string(code,code_body);
end
code[#code+1] = code_end;

local unpack = table.unpack or unpack;

local src = table.concat(code);

io.open('log','w'):write(src);

if load and loadstring then load = loadstring; end

local func,err = load(src);

if not func then
    print("[codeload error] "..err);
end

local s = os.clock() * 1000;
    local state, result = pcall(func);
local e = os.clock() * 1000;

if not state then
  print(result);
end
-- luau аргументы не видит
local name = arg[1] or arg[0];
print("lua "..name.. " >>> "..string.format("%0.3f",e-s).." ms");
end

if arg[2] == nil then
   print("------- Test 1000000 calls function --------")
   os.execute('lua5.1 bench.lua 5.1 run');
   os.execute('lua5.2 bench.lua 5.2 run');
   os.execute('lua5.3 bench.lua 5.3 run');
   os.execute('lua5.4 bench.lua 5.4 run');
   os.execute('luajit bench.lua jit run');
   os.execute('./pluto bench.lua pluto run'); --скомпилированный файлик должен
   os.execute('./luau bench.lua luau run');   --(и этот тоже) валяться в каталоге бенча
end

Запустить просто lua bench.lua для luau я писал полученный буфер в файл и сразу делал os.exit() и уже отдельно запускал.

  • lua bench.lua режим запуска всех бенчей
  • luaXYZ bench.lua XYZ run режим зупуска бенча той lua которая сейчас запускает бенч.

Для luau второй режим надо поправить, мне не хоца, проще записать в файл и от туда запускать.

Короче эта приблуда просто для теста больших файлов с сотнями тысяч вызовов чего-то, сейчас просто функция + сложения, а так перемножение таблиц через свойство метатаблю __add как GLSL типа матрицы калькулировать просто table = tableA * tableB где

tableA={
 xx,xy,xz,xw,
 yx,yy,yz,yw,
 zx,zy,zz,zw,
 wx,wy,wz,ww,
}
LINUX-ORG-RU ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.