Текущий архив: 2008.10.12;
Скачать: CL | DM;
Вниз
Анонимные методы в будущем Тибуроне Найти похожие ветки
← →
MBo © (2008-08-15 10:44) [0]Не понимаю, для чего в язык вводится новая конструкция
TSimpleProc = reference to procedure(x: Integer);
http://blogs.codegear.com/andreanolanusse/2008/07/17/tiburon-anonymous-methods/
Разве нельзя в данном случае было обойтись старыми добрыми процедурными типами TSimpleProc = procedure(x: Integer); ?
Или я не вижу чего-то глубинного?
← →
Anatoly Podgoretsky © (2008-08-15 10:55) [1]> MBo (15.08.2008 10:44:00) [0]
Популисткая мера.
Последствия могут быть плохими, а по Паркинсону будут.
← →
Игорь Шевченко © (2008-08-15 10:59) [2]"Всякий овощ приносит пользу, будучи употреблен надлежащим образом в надлежащее время".
Наверняка найдется такой код, где применение таких конструкций будет вполне оправдано. Другое дело, что народ будет использовать фичу ради фичи, превращая код в нечто абсолютно нечитаемой и несопровождаемое. Зато "типа круто".
Впрочем, с хелперами и с дженериками все с точностью то же самое - идея неплохая, а извраты воспаленного мозга при использовании эту идею дискредитируют.
← →
Alex Konshin © (2008-08-15 11:07) [3]Всё уже украдено до нас (c) Операция Ы.
Это было давно в Algol 68.
Вообще-то если они при этом уберут старый синтаксис (TSimpleProc = procedure(x: Integer);), то будет явно более однозначный синксис. Сейчас синтаксис неоднозначный или, по крайней мере, не очевиден. Например,
попробуй понять такое с ходу:
type TSimpleProc = function : Object;
var pp : TSimpleProc;
...
if pp=nil then
...
Вот и пойми, что тут имелось в виду и как же именно записать то, что действительно хочешь (для шибко много знающих замечу, что об операторах @ и Address() я в курсе).
Короче, если они поменяют синтаксис в сторону функционального языка типа Algol 68, то будет намного лучше. Всё-таки теперешний синтаксис Pascal местами просто уродлив и выглядит анахронизмом.
← →
Polevi © (2008-08-15 11:10) [4]анонимные методы сами по себе хороши.. замыкания и все такое..
а вот смысл в reference to procedure я тоже чтото не уловил
← →
jack128_ (2008-08-15 11:17) [5]
> Или я не вижу чего-то глубинного?
скорее всего компилер так устроен, ему нужно явное указание
Func(10) - это вызов ссылки на анонимную или обычную функцию...
← →
Ega23 © (2008-08-15 11:19) [6]
> Вот и пойми, что тут имелось в виду и как же именно записать
> то, что действительно хочешь (для шибко много знающих замечу,
> что об операторах @ и Address() я в курсе).
Да, хороший пример.
Но, насколько я понимаю, в данной ситуации нельзя таким образом именно адрес метода (не результат) проверять. Надо через Assigned. Тогда понятно будет:if Assigned(pp) then
if pp=nil then ...
← →
Alex Konshin © (2008-08-15 11:23) [7]> Ega23 © (15.08.08 11:19) [6]
> > Вот и пойми, что тут имелось в виду и как же именно записать
> > то, что действительно хочешь (для шибко много знающих
> замечу,> что об операторах @ и Address() я в курсе).Да,
> хороший пример. Но, насколько я понимаю, в данной ситуации
> нельзя таким образом именно адрес метода (не результат)
> проверять. Надо через Assigned. Тогда понятно будет:
Тогда я тебя попрошу написать пример для ссылки на ссылку на функцию, выдающую объект. Вот на старом Algol 68 это было очевидно. На C/C++ не так очевидно, но можно. А вот на Pascal... без бутылки точно не разберёшь.
← →
Рамиль © (2008-08-15 11:27) [8]
> Alex Konshin © (15.08.08 11:23) [7]
Интуитивно понятный код - это когда интуитивно понятно, это - код. © bash.org.ru
← →
jack128_ (2008-08-15 11:34) [9]
> Тогда я тебя попрошу написать пример для ссылки на ссылку
> на функцию, выдающую объект.
@(Pointer(@PP)) ?? :-)
Только не понятно, как ввод reference to решит эту проблему??
← →
Ega23 © (2008-08-15 11:35) [10]
> пример для ссылки на ссылку на функцию, выдающую объект.
:) Ты сначала приведи нормальные (не академический) пример, где без этого действительно никак не обойтись: ссылки на ссылку на функцию ,возвращающую чего-то-там.
← →
Alex Konshin © (2008-08-15 11:41) [11]> Ega23 © (15.08.08 11:35) [10]
> > пример для ссылки на ссылку на функцию, выдающую объект.
> :) Ты сначала приведи нормальные (не академический) пример,
> где без этого действительно никак не обойтись: ссылки на
> ссылку на функцию ,возвращающую чего-то-там.
Элементарно. Это может понадобится, если у тебя есть несколько векторов функций и по ним нужно как-то перемещаться. Вот как раз-таки из-за того, что в Pascal это совершенно нечитаемо, такой код редко встретишь. На C/C++ таких примеров - завались. А на Algol 68 это были вообще задачки для начинающих студентов.
← →
Ega23 © (2008-08-15 11:47) [12]
> Вот как раз-таки из-за того, что в Pascal это совершенно
> нечитаемо, такой код редко встретишь.
Дело не в том, что это "читаемо - не читаемо". По мне, так весь С как-то не очень читаемый. Дело-то не в этом.
Мне просто архитектурно как-то сложно себе представить, нафига иметь указатель на указатель на что-то. Почему не просто указатель на что-то?
← →
Alex Konshin © (2008-08-15 11:49) [13]Вот, кстати, пример вектора функций - VMT. А указатель на него - это указатель на класс. Правда в VMT типы функций разные.
← →
Игорь Шевченко © (2008-08-15 11:50) [14]
> По мне, так весь С как-то не очень читаемый
Сам ты не очень читаемый :) Нормальный язык, код, грамотно на нем написанный, читается без проблем. А нечитаемо на любом языке можно написать, даже на русском.
← →
Alex Konshin © (2008-08-15 11:51) [15]Вот, например, захочется тебе интерпретатор Forth или Lisp реализовать на Pascal, а там сплошные указатели многоэтажные...
← →
Alex Konshin © (2008-08-15 11:57) [16]К слову, одно из последних нововведений в Delphi мне не очень нравится именно по той же причине - появление неоднозначностей. Сейчас можно не указывать ^ для разыменования указателей на запись. Вот именно то, что можно и так, и эдак, мне не нравится.
← →
Ega23 © (2008-08-15 12:01) [17]
> Сам ты не очень читаемый :) Нормальный язык, код, грамотно
> на нем написанный, читается без проблем. А нечитаемо на
> любом языке можно написать, даже на русском.
Это всё субъективно.
Да и редко встретишь грамотно написанный и читабельный код от чистого сишного кодера. Всегда просматривается подспудное желание записать одной строкой то, что можно написать в пять строк... :)
← →
ketmar © (2008-08-15 12:02) [18]>[12] Ega23 © (2008-08-15 11:47:00)
>По мне, так весь С как-то не очень читаемый
дело привычки.
---
Do what thou wilt shall be the whole of the Law.
← →
Ega23 © (2008-08-15 12:07) [19]
> дело привычки.
Вполне вероятно.
← →
DevilDevil © (2008-08-15 13:17) [20]ребята, курите бамбук.
лямбда имеет совсем другое предназначение, нежели обычный указатель на функцию.
← →
Alkid © (2008-08-15 13:32) [21]
> Да и редко встретишь грамотно написанный и читабельный код
> от чистого сишного кодера. Всегда просматривается подспудное
> желание записать одной строкой то, что можно написать в
> пять строк... :)
Кстати, это уже не модно :)
> лямбда имеет совсем другое предназначение, нежели обычный
> указатель на функцию.
+1
← →
Игорь Шевченко © (2008-08-15 14:01) [22]Ega23 © (15.08.08 12:01) [17]
> Да и редко встретишь грамотно написанный и читабельный код
> от чистого сишного кодера. Всегда просматривается подспудное
> желание записать одной строкой то, что можно написать в
> пять строк... :)
Исходники Unix посмотри - именно "грамотно написанный и читабельный код". Я имею в виду именно, С, без плюсов.
← →
ketmar © (2008-08-15 14:35) [23]>[22] Игорь Шевченко © (2008-08-15 14:01:00)
plan9, кстати, тоже.
---
Understanding is not required. Only obedience.
← →
oxffff © (2008-08-15 15:30) [24]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 явно принимает скрытый параметр.
← →
Anatoly Podgoretsky © (2008-08-15 15:38) [25]> Alex Konshin (15.08.2008 11:57:16) [16]
Да нет здесь никакой неодназначности, если применять там где положено X.Y и X^.Y в обеих случаях ясно и однозначно, что надо обратиться к члену Y
А вот X и X^ другое дело, но оно никакого отношения к нововведению не имет, хоть в Паскале Вирта, хоть в Д2009 одинаково.
← →
McSimm © (2008-08-15 15:43) [26]Интересно, как будет работать, если во втором примере по ссылке функцию MakeAdder объявить с var параметром.
← →
McSimm © (2008-08-15 15:45) [27]
> oxffff © (15.08.08 15:30) [24]
Не увидел этого. Т.е. все равно по значению и последующее изменение параметра не изменяет полученную функцию, так ?
← →
oxffff © (2008-08-15 15:45) [28]
> oxffff © (15.08.08 15:30) [24]
Постраюсь пояснить для чего это надо.
Допустим у нас есть процедура которая принимает 5 параметров.
Один из них другая процедура, которая принимает 10 параметров.
Например нам нужно вызвать первую процедуру и передать параметры(snapshot) для второй процедуры(причем внешняя процедуа не определяет все параметры). Как сделать.
Расширять интрефейс первой процедуры можно. А что если нам нужно передать во вторую процедуру еще процедуры и так далее.
Однако можно постутить проще можно создать для каждой процедуры объект который хранит состояние на момент вызова. И передавать в процедуры его. Делать это вручную накладно. За нас это может сделать компилятор.
Это тоже самое как мы пользуемся procedure of object.
А данном случае ссылка на объект есть замыкание.
← →
McSimm © (2008-08-15 15:48) [29]
> который хранит состояние на момент вызова.
на момент создания ?
← →
MBo © (2008-08-15 15:50) [30]>oxffff
У меня страница блога из первого поста теперь наконец загрузилась полностью, и, как оказалось, появились комментарии, в которых автор приводит некоторые пояснения того же Barry Kelly насчет того, что ссылка на анон.процедуру - управляемый тип с вытекающими последствиями, что в в общем-то согласуется с Вашим постом
Однако толком я осознать принципы (а главное - полезность) данной системы не могу, вероятно, из-за того, что пока не понимаю closure (замыкание). Видимо, придется разбираться глубже.
← →
oxffff © (2008-08-15 15:53) [31]
> McSimm © (15.08.08 15:45) [27]
>
> > oxffff © (15.08.08 15:30) [24]
>
> Не увидел этого. Т.е. все равно по значению и последующее
> изменение параметра не изменяет полученную функцию, так
> ?
То есть ли ты объявляешь функцию с параметром, которая возвращает reference to procedure , и делаешь в ней какие то манипуляции с ним(параметром внутри) .
То произойдет захват поскольку фактически параметр со стека будет скопирован в объект-замыкание и все изменения будут происходить в нем.
Аналогично для локальных переменных. Это общая технология.
Конкретная реализация в Delphi мне не известна. Barry Kelly молчит.
Видимо его прижали за яйца, поскольку и так много сказал.
← →
oxffff © (2008-08-15 15:57) [32]
> MBo © (15.08.08 15:50) [30]
Рекомендую поставить ILDASM и посмотреть реализацию на .NET, отличие в том, что delphi нужно прикрутить подсчет ссылок на объект.
B видимо различных правилах захвата.
Безусловно мы можем определять эти объекты сами.
Но тогда потеряеться выразительность LINQ запроса.
Да и рефакторинг и расширение будет ручное сложное.
← →
oxffff © (2008-08-15 15:58) [33]
> MBo © (15.08.08 15:50) [30]
oxffff © (15.08.08 15:45) [28]
← →
McSimm © (2008-08-15 16:03) [34]
> 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?
← →
McSimm © (2008-08-15 16:04) [35]или то же самое про использование глобальных переменных внутри замыканий
← →
MBo © (2008-08-15 16:06) [36]>oxffff © (15.08.08 15:58) [33]
почитал в wiki, и пока это closure для меня выглядит подобно вложенным функциям в Паскале, имеющим доступ к переменным внешней функции (и более глобальным), а кроме того, как следует из [28] - к личным параметрам данного closure (как поля объекта).
← →
oxffff © (2008-08-15 16:26) [37]
> 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]
← →
ketmar © (2008-08-15 17:22) [38]забавно. но не ясно, нафига тащить в язык то, что ему подходит как корове макияж.
---
All Your Base Are Belong to Us
← →
DevilDevil (2008-08-15 18:05) [39]> ketmar © (15.08.08 17:22) [38]
> забавно. но не ясно, нафига тащить в язык то,
> что ему подходит как корове макияж.
если в язык добавят макросы, шаблоны (уже добавили), классы на стеке с автоконструктором/автодеструктором и увеличат качество компиляции, то лично твоя реакция будет аналогичной. Если вещи добавляют, значит в них есть спрос/удобство. Если ту или иную возможность к своим задачам применить не можешь, это далеко не даёт тебе права настолько резко высказываться.
← →
ketmar © (2008-08-15 18:15) [40]>[39] DevilDevil (2008-08-15 18:05:00)
«право высказываться» у меня отъемлемо только модераторами. это доступно?
алсо: я знал и использовал closures & lambda calculus когда ты ещё не то, что кода не писал, а даже игрушки с трудом запускал. если ты не понял, о чём я — промолчи, сойдёшь за умного.
---
Do what thou wilt shall be the whole of the Law.
Страницы: 1 2 3 вся ветка
Текущий архив: 2008.10.12;
Скачать: CL | DM;
Память: 0.59 MB
Время: 0.019 c