-
ребята, курите бамбук.
лямбда имеет совсем другое предназначение, нежели обычный указатель на функцию.
-
> Да и редко встретишь грамотно написанный и читабельный код
> от чистого сишного кодера. Всегда просматривается подспудное
> желание записать одной строкой то, что можно написать в
> пять строк... :)
Кстати, это уже не модно :)
> лямбда имеет совсем другое предназначение, нежели обычный
> указатель на функцию.
+1
-
Ega23 © (15.08.08 12:01) [17]
> Да и редко встретишь грамотно написанный и читабельный код
> от чистого сишного кодера. Всегда просматривается подспудное
> желание записать одной строкой то, что можно написать в
> пять строк... :)
Исходники Unix посмотри - именно "грамотно написанный и читабельный код". Я имею в виду именно, С, без плюсов.
-
>[22] Игорь Шевченко © (2008-08-15 14:01:00)
plan9, кстати, тоже.
---
Understanding is not required. Only obedience.
-
MBo © (15.08.08 10:44)
Я могу вам помочь!!!
Некий Barry Kelly(входящий в команду разработчиков компилятора), который у себя в комментарий пояснил реализацию ссылки на процедуру.
Фактически reference to procedure(x: Integer) будет являться с интерфейсом с единственным методом с сигнатурой описанной процедуры.
Основная вкусность в том, что происходит захват переменных,
Что это
1. Создается объект кучи(у которого есть интерфейс с методом сигнатурой аномимного метода, который(интерфейс) в дальнейшем и будет являться значением переменной reference to procedure)
2. Его поля фактически будут представлять набор переменных вызова (snapshot окружения).
3. В дальнейшем я думую, такое упрощенное определения объекта замыкания(все работу за нас делает компилятор) приведет к некоему подобию LINQ C#.
Однако есть вопросы которые требуют ответа.
Например захват value типов в С# происходит по значению, а поля managed типов по ссылке.
А поскольку в delphi куча не управляемая, и объекты не имеют интерфейса для подсчета времени своего существования (например из-за проблемы зацикливания), то я думаю поля объектов тоже будут захватываться по значению. Ему(Barry Kelly) задали этот вопрос две недели назад. Но правила захвата он не пояснил.
То есть переменных стека не используются и использоваться а потом копироваться, например при захвате входящего параметра)
создается объект с единственным методом.
значения которых фактически копируются в объект кучи.
Хотя если посмотреть внимательно, то замыкание в Delphi присутствовало c самого рождения.
А именно procedure of object явно принимает скрытый параметр.
-
> Alex Konshin (15.08.2008 11:57:16) [16]
Да нет здесь никакой неодназначности, если применять там где положено X.Y и X^.Y в обеих случаях ясно и однозначно, что надо обратиться к члену Y
А вот X и X^ другое дело, но оно никакого отношения к нововведению не имет, хоть в Паскале Вирта, хоть в Д2009 одинаково.
-
Интересно, как будет работать, если во втором примере по ссылке функцию MakeAdder объявить с var параметром.
-
> oxffff © (15.08.08 15:30) [24]
Не увидел этого. Т.е. все равно по значению и последующее изменение параметра не изменяет полученную функцию, так ?
-
> oxffff © (15.08.08 15:30) [24]
Постраюсь пояснить для чего это надо.
Допустим у нас есть процедура которая принимает 5 параметров.
Один из них другая процедура, которая принимает 10 параметров.
Например нам нужно вызвать первую процедуру и передать параметры(snapshot) для второй процедуры(причем внешняя процедуа не определяет все параметры). Как сделать.
Расширять интрефейс первой процедуры можно. А что если нам нужно передать во вторую процедуру еще процедуры и так далее.
Однако можно постутить проще можно создать для каждой процедуры объект который хранит состояние на момент вызова. И передавать в процедуры его. Делать это вручную накладно. За нас это может сделать компилятор.
Это тоже самое как мы пользуемся procedure of object.
А данном случае ссылка на объект есть замыкание.
-
> который хранит состояние на момент вызова.
на момент создания ?
-
>oxffff
У меня страница блога из первого поста теперь наконец загрузилась полностью, и, как оказалось, появились комментарии, в которых автор приводит некоторые пояснения того же Barry Kelly насчет того, что ссылка на анон.процедуру - управляемый тип с вытекающими последствиями, что в в общем-то согласуется с Вашим постом
Однако толком я осознать принципы (а главное - полезность) данной системы не могу, вероятно, из-за того, что пока не понимаю closure (замыкание). Видимо, придется разбираться глубже.
-
> McSimm © (15.08.08 15:45) [27]
>
> > oxffff © (15.08.08 15:30) [24]
>
> Не увидел этого. Т.е. все равно по значению и последующее
> изменение параметра не изменяет полученную функцию, так
> ?
То есть ли ты объявляешь функцию с параметром, которая возвращает reference to procedure , и делаешь в ней какие то манипуляции с ним(параметром внутри) .
То произойдет захват поскольку фактически параметр со стека будет скопирован в объект-замыкание и все изменения будут происходить в нем.
Аналогично для локальных переменных. Это общая технология.
Конкретная реализация в Delphi мне не известна. Barry Kelly молчит.
Видимо его прижали за яйца, поскольку и так много сказал.
-
> MBo © (15.08.08 15:50) [30]
Рекомендую поставить ILDASM и посмотреть реализацию на .NET, отличие в том, что delphi нужно прикрутить подсчет ссылок на объект.
B видимо различных правилах захвата.
Безусловно мы можем определять эти объекты сами.
Но тогда потеряеться выразительность LINQ запроса.
Да и рефакторинг и расширение будет ручное сложное.
-
> MBo © (15.08.08 15:50) [30]
oxffff © (15.08.08 15:45) [28]
-
> oxffff © (15.08.08 15:53) [31]
Не совсем понял, я имел в виду:
function MakeAdder(var y: Integer): TFuncOfInt;
begin
MakeAdder :=
function(x: Integer): Integer
begin
Result := x+y;
end;
end;
var
adder: TFuncOfInt;
I: Integer;
begin
I := 20;
adder := MakeAdder(I);
I := 30; // <- это влияет на уже созданное замыкание adder?
-
или то же самое про использование глобальных переменных внутри замыканий
-
>oxffff © (15.08.08 15:58) [33]
почитал в wiki, и пока это closure для меня выглядит подобно вложенным функциям в Паскале, имеющим доступ к переменным внешней функции (и более глобальным), а кроме того, как следует из [28] - к личным параметрам данного closure (как поля объекта).
-
> McSimm © (15.08.08 16:03) [34]
Я говорю, что не знаю правила захвата в реализации Delphi.
Поскольку время жизни var параметра не известно, а код создания и инициализация объекта замыкания расположен внутри MakeAdder, то
1. Либо запрещено захватывать объекты по ссылке.
2. Либо копирование значения и использование копии в качестве переменной внутри аноноимного метода.
> MBo © (15.08.08 16:06) [36]
Отличие в том, что вложенные процедуры нельзя передавать в качестве параметра поскольку фрейм стека вызывающего должен присутствовать в момент вызова вложенной процедуры. И переменные разделяются.
А здесь они вычленяются в отдельную сущность которая может жить сама по себе, пока последняяя ссылка не прикажет Retire
Поскольку MakeAdder(var y: Integer): TFuncOfInt;
> MBo © (15.08.08 16:06) [36]
-
забавно. но не ясно, нафига тащить в язык то, что ему подходит как корове макияж.
---
All Your Base Are Belong to Us
-
> ketmar © (15.08.08 17:22) [38]
> забавно. но не ясно, нафига тащить в язык то,
> что ему подходит как корове макияж.
если в язык добавят макросы, шаблоны (уже добавили), классы на стеке с автоконструктором/автодеструктором и увеличат качество компиляции, то лично твоя реакция будет аналогичной. Если вещи добавляют, значит в них есть спрос/удобство. Если ту или иную возможность к своим задачам применить не можешь, это далеко не даёт тебе права настолько резко высказываться.