LINUX.ORG.RU

Вышла Lua 5.2

 ,


0

0

Завершена работа над новой версией популярного встраиваемого языка програмирования Lua. Выпущены руководство (reference manual) с описанием новой версии языка (5.2), набор тестов для реализаций Lua версии 5.2 и образцовый (референсный) интерпретатор версии 5.2.0.

Вот основные изменения в новой версии языка:

  • Можно вызывать yield из защищенного вызова (pcall) и метаметодов.
  • Новый метод работы с окружениями и глобальными переменными. В частности, функции getfenv/setfenv больше не работают.
  • Появилось стандартное API для битовых операций.
  • Изменение в C API: появились т.н. «облегченные нативные функции» («light C functions»), представляющие собой простые указатели на функции. В отличие от полноценных замыканий, они не имеют окружения, что позволяет экономить системные ресурсы.
  • В языке появился оператор goto.
  • Изменение в сборке мусора: таблицы со слабыми ссылками на ключи и с сильными ссылками на значения теперь будут работать как таблицы эфемеронов.
  • Теперь у таблиц могут быть финализаторы.
  • Помимо уже существующего инкрементного сборщика мусора, интерпретатор теперь имеет экстренный сборщик мусора, который освобождает память, если не удается выделить новую. Кроме того, появился экспериментальный сборщик мусора с учетом поколений (generational GC), но он по умолчанию отключен.

Полный список изменений можно прочитать в файле README, находящемся в дистрибутиве Lua.

Нововведения в языке привели к несовместимости Lua 5.2 и 5.1. Возникшие проблемы совместимости задокументированы в руководстве. Впрочем, теоретически существует возможность написать программу так, чтобы она исполнялась и на Lua 5.1, и на 5.2. Lua не стремится сохранять обратную совместимость: например, версия 5.1 не была совместима с 5.0. Разработчики отмечают, что совершенно необязательно переводить существующие приложения со скриптингом на Lua на новую версию языка.

С момента выпуска Lua 5.1 прошло около четырех лет. Первая альфа-версия 5.2 вышла примерно год назад. Образцовый интерпретатор распространяется по лицензии MIT.

>>> Сайт Lua

★★★★★

Проверено: maxcom ()
Последнее исправление: proud_anon (всего исправлений: 4)
Ответ на: комментарий от proud_anon

Этого достаточно, чтобы организовать неструктурную обработку исключений, разве нет?

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

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

Смотря с какой стороны посмотреть.

Я люблю исключения и не воспринимаю их как только способ уведомить об *исключительной* ситуации

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

Я люблю исключения и не воспринимаю их как только способ уведомить об *исключительной* ситуации

Использование исключений не по назначению усложняет код и делает его менее читабельным.

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

таких if обычно штук 5-10. Предлагаешь на каждый if делать else?

А почему нет?

int func() {
	int result = OK;

	if (!check1())
		result = ERROR1;
	else if (!check2())
		result = ERROR2;
	else if (!check3())
		result = ERROR3;
	else if (!check4())
		result = ERROR4;
	...
	...

	else if (!check10())
		result = ERROR10;
	else {
	 	/* do what we want to do */
	}

	return result;
}
Но я опять же говорю - реальный алгоритм может быть сложнее, и в каждом if-е может быть ещё куча вложенных if-ов. Тогда, чтобы текст не «уехал» вправо с экрана совсем, лучше использовать goto.

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

Да ну? А по мне те же interruption points вполне себе хитрая и изящная идея.

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

Во-вторых, отловить его можно только на уровне не ниже функции и только если функция эта вызвана через [x]pcall().

Это правда.

Во-первых, «исключение» тут всегда одно - аварийное завершение программы. (...) Никто же ExitProc в паскале не называет обработкой исключений :)

Так ведь нет же! В том и отличие от ExitProc в Паскале (если я не ошибаюсь). При возникновении ошибки pcall вернется и программа может спокойно продолжить работу. И в качестве сообщения об ошибки можно послать любой тип данных, в т.ч., например, таблицу.

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

Да я ж тебе говорю - реальные алгоритмы могут быть сложнее, и без goto бывает не обойтись. Хотя ресурсы перед фейлом можно освобождать и без goto.

int func() {

	alloc_resource1();

	do {

		if (fail1())
			break;
		...

		if (fail2())
			break;
		...

		alloc_resource2();

		do {
			if (fail3())
				break;
			...

			if (fail4())
				break;
			...

			alloc_resource3();

			do {
				if (fail5())
					break;
				...

				if (fail6())
					break;
				...
			}
			while(0);

			free_resource3();
		}
		while (0);

		free_resource2();
	}
	while (0);

	free_resource1();

}
Почти как сиплюсплюсные исключения :) Правда, при большой вложенности такой подход, конечно, не годится, как не годятся и сиплюсплюсные исключения.

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

Хотя ресурсы перед фейлом можно освобождать и без goto.

в gcc и clang есть __attribute__(cleanup)

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

вот потому и пользуют goto, чтоб не было такого треша. И всё просто и понятно.

anonymous
()

зачем «это», если есть пайтон? %)

niXman ★★★
()
Ответ на: комментарий от anonymous
int r;
r = init1();
if(r != OK)
  goto out;
r = init2();
if(r != OK)
  goto free1;
r = init3();
if(r != OK)
  goto free2;

return OK;

free2:
cleanup2();
free1:
cleanup1();
out:
return FAIL;

скажи мне, что это чудовищно сложно для понимания.

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

Ахахаха! Для понимания это очень просто. Поэтому, я думаю, ты сам без труда сможешь увидеть, почему твой код неправильный.

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

Это вообще-то ни в каком виде не исключения.

Исключения, это вообще-то ни в каком виде не исключения.

throw, это просто аварийное завершение программы с выводом сообщения, а try/catch - «безопасные» скопы, для которых throw() не приводит к завершению программы, а завершает только текущий скоп и возвращает переданное сообщение.

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

Лишний return в середине функции тоже считается злом™

кстати, в lua код

function test ()
...
return
x=x+1
end

вызывает сообщение об ошибке. Оно правильно, но тяжко бывает при отладке.

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

Ну, не знаю... Во-первых, «исключение» тут всегда одно - аварийное завершение программы.

не программы, а скопа. скоп, это или программа или функция.

Во-вторых, отловить его можно только на уровне не ниже функции и только если функция эта вызвана через [x]pcall()

В lua есть анонимные функции, которые можно определять где угодно, так что это вопрос синтаксиса.

только если функция эта вызвана через [x]pcall()

Во первых, это не так. Можно переопределить глобальный обработчик и все исключения будут в него падать.

А во вторых, можно мне увидеть обработку исключений вне блока try/catch?

И в последних, в луа есть метапрограммирование, в котором реализован стандартный try/catch , но это скорее дань классике, нежели ответ на реальные потребности.

В луа вообще легко реализуются самые странные запросы. Базовыми средствами языка реализуются модули, классы, исключения и тп. В этом его сила...

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

Хорошо, какая часть «ядра»? kernel32.dll - это тоже, знаешь ли, «ядро». Но это немножко не то ядро, которое ntdll.dll


kernel32.dll - это нихрена не ядро, это юзерспейсная библиотека. Как и ntdll.dll. Это типа libc в *nix. Ядро - это ntoskrnl.exe

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

не программы, а скопа. скоп, это или программа или функция.

Неправда. Скоп - это также, например, блок

for i = 1, n do
...
end
но если ты вызовешь в этом блоке error(), то завершится отнюдь не оператор for.

В lua есть анонимные функции, которые можно определять где угодно, так что это вопрос синтаксиса.

Поименованные функции там тоже можно определять где угодно, но к исключениям они имеют такое же отношение, как и анонимные.

Во первых, это не так. Можно переопределить глобальный обработчик и все исключения будут в него падать.

Можно, конечно. Можно и в С++ использовать один обработчик на все исключения. Тогда и try/catch не нужны - есть же signal()! Как вы думаете, зачем их придумали?

А во вторых, можно мне увидеть обработку исключений вне блока try/catch?

Да можно и через задний проход гланды удалять, но зачем? throw придуман не для того, чтобы аварийно завершать программу и не для того, чтобы использовать его как-то без try/catch.

И в последних, в луа есть метапрограммирование, в котором реализован стандартный try/catch , но это скорее дань классике, нежели ответ на реальные потребности.

А с этого места, пожалуйста, поподробнее. Очень интересно было бы узнать о метапрограммировании в Луа, «в котором реализован стандартный try/catch» :)

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

Неправда. Скоп - это также, например, блок

В луа этот блок выглядит так:

pcall(function () for i = 1, n do ... end end )

Да можно и через задний проход гланды удалять, но зачем? throw придуман не для того, чтобы аварийно завершать программу и не для того, чтобы использовать его как-то без try/catch.

на это и был намек. Разница только в синтаксисе. В одном случае это try ...скоп... catch, а в другом pcall(function() ...скоп... end)

причем луашный синтаксис более универсален, поскольку позволяет еще и параметры в скоп кидать. Попробуйте наваять в try/catch аналог

result,err = pcall(function (sql) ... return (query_result) end,«select * from mytable»)

if not result then print((«все пропало! Простой запрос %s в базу обернулся %s!!!»):format(sql,err)) end

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

А с этого места, пожалуйста, поподробнее.

http://metalua.luaforge.net/metalua-manual.html#htoc55

http://metalua.luaforge.net

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

Использование исключений не по назначению усложняет код и делает его менее читабельным.

Ты забыл добавить: " в С++" Ибо в других языках такого не наблюдается.

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

Попробуйте наваять в try/catch аналог

def pcall(func, *args, **kwargs):
    try:
        result = func(*args, **kwargs)
    except Exception as e:
        return None, e
    else:
        return result, None

Заметь, никакого метарасширения мне не понадобилось. try...catch удобен сразу несколькими вещами:

1) Читаемость

2) Диспатчинг, в зависимости от типа исключения

3) finally

Очень глупо заменять это на ручной pcall. Просто луа убог. Бесконечно убог. Радует что некоторые подвижки в этом плане начались.

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

Если я правильно понял замысел, то нужно так:

struct device *dev = &(self->ndev->dev);

goto нужен однозначно.

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

а goto - возвращение в каменный век. Зачем оно?

Как предлагаешь выходить из нескольких вложенных циклов но не куда попало а в нужный цикл? И как обработать без goto десяток забористых условий, количество которых может измениться - писать всё в одну строку?

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

Или специальный флаг

Сработает не сразу.

и православный оператор break?

Выкидывает не туда куда тебе надо а куда ему надо и ищи потом в коде место, куда они переносят. break ухудшает чтение программы.

Особенно хорош вариант с отдельной процедурой и return, он предполагает сильную декомпозицию программы и многократное использование процедуры в разных местах программы.

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

Прямой аналог действия goto, только кошерный:)

А деревянный велосипед прямой аналог гоночного внедорожника.

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

Выкидывает не туда куда тебе надо а куда ему надо и ищи потом в коде место, куда они переносят. break ухудшает чтение программы.

4.2. break выкидывает в едино правильное место, куда допустим выход из цикла - на первую инструкцию после цикла.

И в обработчиках событий дочерних форм вынесение некоторого кода в отдельную процедуру чревато поломкой стека.

??? У тебя стэк 128 байт?

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

В других языках не наблюдается жажды использовать исключения не по назначению.

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

А зачем goto при обработке кучи условий?

В принципе это одно условие но в нём внутри так много условий и противоречий что при написании оно ну очень плохо помещается в голове. Но если использовать goto, то всё очень красиво реструктуризируется и потом проще эти условия патчить.

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

4.2. break выкидывает в едино правильное место, куда допустим выход из цикла - на первую инструкцию после цикла.

Какого именно цикла? Их много и не всегда необходимо выходить сразу из всех.

??? У тебя стэк 128 байт?

Половые проблемы ООП, в отладчике не смотрел, мне это малоинтересно.

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

Какого именно цикла? Их много и не всегда необходимо выходить сразу из всех.

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

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

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

break с меткой

У нас такой сущности нет, незачем дублировать функщионал goto.

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

Пример в студию.

Генерация событий на основе анализа запутанной левой информации. Всяких многоэтажных if a=1 then if a=q then if aaa[a].zzz[x+qqq[zz].xx[z].q]=zzz[x+qqq[zz+zzz[x+qqq[zz].xx[z+1].q]].xx[z].q] then... может не хватить для принятия решения.

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

Покажи, каким образом эта проблема привязана к ООП.

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

Napilnik ★★★★★
()

В языке появился оператор goto.

Отлично. Он там вычисляемый?

buddhist ★★★★★
()

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

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

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

Заметь, никакого метарасширения мне не понадобилось.

Ты из try/catch написал метарасширение - pcall. А в lua ровно наоборот.

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

try...catch удобен сразу несколькими вещами:

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

Очень глупо заменять это на ручной pcall. Просто луа убог. Бесконечно убог.

Он бесконечно прост и универсален.

Радует что некоторые подвижки в этом плане начались.

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

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

Они положили Юникод в коробку?

нет.

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

Металуа как и большинство расширений луы написан много лет назад. Если кто-то открывает его только сейчас, это не делает его новым...

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

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

Да я не про металуа, а про новость. Изменения просто грандиозные.

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

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

Такими темпами он довольно скоро перестанет быть встраиваемым.

Размер луы и его прадигма вообще не изменились.

Думаю в 5.4 появится нормальная стандартная библиотека.

rpm -qi python | grep Size

Size : 23000444 License: Python

[user@marina ~]$ rpm -qi lua | grep Size

Size : 618031 License: MIT

Нуна?

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

В некоторых языках, вроде java, break имеет возможность перехода на меткую Это куда более красивое решение. И логичное. Ну и надо так составлять условия цикла, Что-бы выход не по условию был исключительным действием,  не правилом. Чем меньше безусловных переходов - тем лучше. переход должен быть ещё одним вариантом использование break, nе более. А то умельцы не только в циклах его используют, iногда код превращается в лапшу в стиле всеми любимого bash.

lucentcode ★★★★★
()

Как показывает практика слепое следование рекомендациям для студентов вида «не использовать goto» или «один return на функцию» и т.п. может запутать код куда больше чем goto. Хотя я за 7 лет программирования на Си/Си++ goto использовал 2 раза и то позже нашлось решение покрасивее без него. Сам человека использующего goto возьму на работу максимум как junior'а. Т.к. считаю что он необходим только для очень низкоуровневых оптимизаций (читай как «для оптимизаций уровня ядра ОС» или критичных алгоритмов), а у нас они не требуются. Более того, goto компилятор уже никак не может оптимизировать в отличии от более высокоуровневых конструкций.

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

GOTO идеален для замены конструкций, заменяющих GOTO, когда нет конструкций, заменяющих GOTO :-)

no-dashi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.