LINUX.ORG.RU

Lua 5.5.0

 ,

Lua 5.5.0

0

3

15 декабря, спустя примерно шесть месяцев после публикации предварительной бета версии, утверждён, сформирован и опубликован стабильный выпуск 5.5.0 языка программирования Lua.

Финальное уведомление сообщества о событии произошло вчера, 22 декабря, в списке рассылки.

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

Благодарим всех, кто принял участие в тестировании и обсуждениях.
И просто всех тех, кто просто пользуется языком Lua для решения своих, как повседневных, так и производственных, промышленных, задач. Спасибо!


Основные изменения по отношению к предыдущей версии языка 5.4.8:

  • Новое ключевое слово global служит для управления глобальной областью видимости. Сразу стоит уточнить, это не просто противоположность ключевому слову local. По умолчанию в каждом исполняемом чанке, происходит неявное объявление global *, при этом ничего не происходит – код работает точно так же, как и прежде. Объявление global со звёздочкой * указывает на то, что все глобальные переменные просто доступны глобально. При желании можно записать это явно, например:

    global *
    print(math.pi)
    

    Таким образом сохраняется старое поведение.

    Если же через global объявить переменную, то вся глобальная область видимости удаляется и в глобальной области видимости будет только эта и все последующие явно декларированные переменные как глобальные, попытка обратится к неявно декларированной глобальной переменной или неявно создать её приведёт к ошибке.

    global x  -- очистить глобальную область видимости и внести в неё "x"
    x = 42    -- допустимо, "х" в глобальной области видимости чанка
    y = 42    -- ошибка переменная "y" не определена
    print(x+y) -- ошибка функция "print" не определена
    

    Если вы используете ключевое слово global не с * то после его использования требуется явно декларировать все используемые вами глобальные переменные:

    global x, y, print
    x = 42
    y = 42
    print(x+y)
    

    или

    global x
    global y
    global print
    print(x+y)
    

    Тем самым вы можете изолировать модуль, тело функции, тело условия или тело цикла от глобальной области видимости и задать её там явно. Вы можете в любой момент времени указать в коде global *, чтобы вернуть видимость всех глобальных переменных назад, для всего последующего за этим объявлением кода. Можно сделать константными все глобальные переменные:

    global <const> *
    

    При этом важно отметить, что global, будучи применённый к таблице, делает константной только таблицу – в неё нельзя внести новые значения, но это не делает константными значения таблицы:

    global <const> math, print -- или global <const> *
    math.pi = 42
    print(math.pi)
    

    Будет выведено 42. Читайте документацию и обсуждение, экспериментируйте.

  • Для обратной совместимости с прошлыми версиями языка, по причине того, что global может использоваться как имя переменной, сейчас возможно использование этого имени и как имени переменной, и как ключевого слова:

    local global = 42
    print(global)
    global <const> x
    x = 42  -- сработает ошибка 
    

    Это поведение обратной совместимости можно отключить на этапе сборки, отключив LUA_COMPAT_GLOBAL.

Другие изменения:

  • Счётчики в циклах for отныне являются константами, попытка их изменения вызывает ошибку, в Lua 5.4 и ниже, изменение значение счётчика в цикле сбрасывалось на следующее значение счётчика, так как счётчики циклов не изменяемые:
for i=1,100 do
    i = 10  -- ошибка для Lua 5.5
    print(i)
end

Если вам нужна переменная с именем счётчика, и совместимость с предыдущими версиями языка, то объявите её как local:

for i=1,100 do
    local i = 10
    print(i)
end
  • float значения печатаются с таким количеством знаков, чтобы быть правильно сконвертированными обратно.
  • Новая функция table.create создаёт новую таблицу с предварительно выделенной памятью, это полезно с точки зрения производительности, когда вы сразу знаете сколько элементов будет в таблице.
  • utf8.offset теперь дополнительно возвращает финальную позицию символа.
print(utf8.offset("привет",2))

Lua 5.4 и ранее, вернут 3, Lua 5.5 вернёт 3 и 4.

  • Lua C API. Внешние строки (external strings) через lua_pushexternalstring для использования данных в обход автоматического управления памяти, строка должна завершаться \0.
  • Lua C API. Новая функция luaL_openselectedlibs в отличии от luaL_openlibs позволяет выборочно загрузить/предзагрузить, нужные части стандартной библиотеки Lua в package.loaded, package.preload из списка:
   LUA_GLIBK : the basic library.
   LUA_LOADLIBK : the package library.
   LUA_COLIBK : the coroutine library.
   LUA_STRLIBK : the string library.
   LUA_UTF8LIBK : the UTF-8 library.
   LUA_TABLIBK : the table library.
   LUA_MATHLIBK : the mathematical library.
   LUA_IOLIBK : the I/O library.
   LUA_OSLIBK : the operating system library.
   LUA_DBLIBK : the debug library.
  • Оптимизация памяти, большие Lua массивы теперь потребляют до 60% меньше памяти:
collectgarbage("stop")

local array = { }
for i=1,10000000 do
    array[i]=i
end

print(collectgarbage("count") * 1024)

Вывод показателей памяти в байтах (потребление памяти, в этом тесте, упало более чем на 40%):

dron@gnu:~/$ lua5.4 mem.lua
268457462.0
dron@gnu:~/$ lua5.5 mem.lua
151015205.0
  • Возможность возврата сложных конструкций вида:
return {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}}}}}}}

Это не работало в 5.4 и выдавало ошибку «function or expression too complex» или «function or expression needs too many registers».

  • Удалена опция сборки LUA_COMPAT_5_3 (совместимость с 5.3);
  • lua.c загружает функцию readline динамически;
  • удалена опция LUA_USE_READLINE и цели сборки linux-readline and linux-noreadline для Linux.

>>> Релиз Lua5.5 релиза в списке рассылки

>>> Онлайн документация

>>> Прямая ссылка на архив исходного кода

>>> Прямая ссылка на архив с тестами

>>> Инструкции по сборке и установке

>>> Полный исходный код в веб-интерфейсе

>>> Подробности

★★★★★

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

Извините конечно, но фигня этот ваш lua. С точки зрения программной он устроен намного больше чем хорошо, очень быстрый, довольно простой, багов почти ноль, классный, но синтаксис у него… в вакууме хороший, но больше 50-ти строк кода превращается в лютые спагетти.

daniyal
()

global x global y global print

Вот тут не совсем понял. Разве использование global не очищает область видимости? Тогда написав global y x должен выйти из области видимости, но почему не выходит?

daniyal
()

Лет 15 назад стоял выбор между мыльницей Canon и зеркалкой Olympus. На мыльнице можно было писать скрипты на Lua для расширения функционала. Выбрал зеркалку, о чём сейчас немного жалею. Вот так мы с Lua и разминулись.

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

На мыльнице можно было писать скрипты на Lua

Круто.


На linux есть что-то типо xonsh, только на lua?

mamina_radost
()
Ответ на: комментарий от daniyal

Первый явный дёрг global очищает, вернее прячет _G глобальную область (кроме _ENV) и декларирует глобальную переменную, последующие только декларируют новые глобальные переменные, завершение области видимости, или прописывание global * возращают всё назад как было изначально, вертая _G, а изначально было неявно написано global *

То есть первый «вызов» global делает два дела, остальные одно дело. В рамках одной области видимости, после выхода из которой всё можешь делать по новой.

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

В смысле писать для мыльницы, а не на мыльнице.

avgust23
()

global – говно, <const> – еще говнее.

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

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

Конст в текущей реализации выглядит как говно ненужное. Если что-то объявляется константным в каком-то контексте его должно быть невозможно в этом контексте менять. Вообще никак менять, а не вот это всё. Плюс стрелочки уродливые. Зачем?

timdorohin ★★★★
()

Вроде и хороший язык, но какая-то печаль от линейки 5.x. Постоянная ломка совместимости на ровном месте, беготня туда-сюда - такое впечатление, что авторы сами не знают, чего хотят. Была функция X в C API, в одном релизе ее заменили на Y, в следующем Y удалили в пользу Z, а что-то еще просто выкинули с комментом «напишите сами, если вам надо»… :/

И язык загромождается всё больше. Все эти global <const> *, эти впихнутые через 20 лет разработки инты выглядят как пришлепки сбоку, чтоб пофиксить изначальную непродуманность. Уж объявили бы фичей и оставили как есть, сохранили бы киллер-фичу - простоту и завидную компактность языка. Вроде уж все приняли его таким, кому он нужен.

Становится всё яснее позиция luaJIT, что развитие 5.x - шляпа, и повторять его они не хотят.

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

С какого бы перепугу превращалось в спагетти, если нормально структурировать код? ООП тебе нахрена дано?

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

Это не функция и не вызов, а декларация. Я в скобочках специально написал :)

Так-то да global в целом сомнителен, но, благо если не нужно, можно просто игнорировать сам факт его существования, так же можно игнорировать целые числа и вообще всё что не нужно. Если что-то явно не использовать, то всё (почти) работает тупо как и раньше, ты можешь писать на lua5.5 как на 5.2 понятия не имея о каких-то нововведениях и ничего не заметишь, за исключением единственного наверное, переменные счётчиков циклов стали константами, нафига, я так и не понял, они один фиг были в рамках итерации неизменяемыми, ну поменять то можешь, но новая итерация сбрасывала всё продолжая инкрементировать/декрементировать, от того сама переменная цикла могла быть использована как самосбрасываемая временная, автоматическая локальная переменная, по сути это была фича, не сказать чтобы это сильно широко использовалось. Короче с циклами ты будешь обязан для работоспособности кода пофиксить код, а про остальное если оно не надо можешь просто не знать и забить болт.

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

Все это конечно интересно, но ждем разделения таблиц на массив, хэштаблица, кортэж…

Не, ну а чо, если уж флоэты ввели.

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

можно просто игнорировать сам факт его существования, так же можно игнорировать целые числа и вообще всё что не нужно

Это когда ты только с нуля свой код пишешь. Когда приходится править чужой, игнорировать уже не получится.

CrX ★★★★★
()

используемый в огромном числе программных продуктов

просто колоссальный список программ, надо же

rechnick ★★★
()

Внезапно, после четырёхлетней паузы: https://gitlab.com/FascinatedBox/lily/-/blob/main/RELEASES.md?ref_type=heads#version-21-2025-7-10.

Version 2.1 (2025-7-10)

After a long hiatus, work on this release started in May of this year. This release is on the smaller side, since it’s only a couple months and some of that time was spent getting reacquainted with the interpreter’s internals.

var doors = List.repeat(100, false)

for i in 0...99: {
    for j in i...99 by i + 1: {
        doors[j] = !doors[j]
    }
}

# The type must be specified since the List starts off empty.
var open_doors: List[Integer] = []

doors.each_index(|i|
    if doors[i]: {
        open_doors.push(i + 1)
    }
)

print("Open doors: {}.".format(open_doors))
dataman ★★★★★
()
Ответ на: комментарий от LightDiver

Нет, ты не понял, тут дело не в структурировании, а в самом синтаксисе. Он неинтуитивен. Если я посмотрю на рандомную функцию в какой-нибудь сишке, я смогу в вакууме определить, что она делает, и немного понять о некоторых дркгих функциях программы. Если я попробую сделать то же самое с луа, то у меня глаза заболят, и придётся смотреть под лупой, чтобы понять, что где куда. И дело тут не в чём-то глобальном, а в мелких банальных вещах вроде for i=1, 100 do. Вроде всё понятно, но for (int i = 1; i <= 100; i++) { в разы понятнее в огромном коде. А это всего лишь цикл for, в коде же таких мелочей много и банально глаза устают в это смотреть

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

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

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

Ну не знаю, лично я с питона сразу на C перешёл и быстро всё понял, но сколько не пытался конфижить awesome - глаза болели из-за чёртового луа

daniyal
()
Ответ на: комментарий от gns

Паскаль. Одновременно не подвержен новомодным влияниям, но и нужные расширения тоже можно найти.

kaldeon
()

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

daniyal:

но синтаксис у него… в вакууме хороший, но больше 50-ти строк кода превращается в лютые спагетти.

Натуральная ЛПП. Есть игра такая, luanti, ранее известная как minetest. По сути, она из себя представляет воксельный движок для запуска кода на луа. Т.е. в отличие от майнкрафта, в ней нет прикрученного болтами «дефолтного ядра», там всё есть мод, даже «default game» просто подборка модов. Собственно, всё настолько пропитано луой, что даже в игре через мод типа mesecons/digiline можно писать на ней программы. Как в меме про «Yo, dawg, we heard you like driving», короче

Так вот, ваш покорный слуга светлейший благодетель уже который код в разработке этих модов участвует (хотя в последнее время и вяло); какие-то форкнул, какие-то сам сделал. И нигде я не видел «спагетти кода». Наоборот, любой мод обычно читается как открытая книга. Вот любой разраб почему-то умудряется код структурировать, расставить отступы, дать нормальные имена переменным и функциям... Так что разруха она не в синтаксисе, она в головах, причём только некоторых!

Smacker ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.