каррирование функции по сравнению с обычным методом обратного вызова

Я пытаюсь понять, чем метод программирования, известный как каррирование, отличается от обычного интерфейса обратного вызова (например, интерфейсов Observer / Observable в Java или классического шаблона проектирования Visitor).

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

Может ли кто-нибудь объяснить ситуацию программирования, которую лучше решить каррированием, чем методом обратного вызова? Каково практическое значение того факта, что каррирование использует отдельную функцию для каждого аргумента?

[update:] резюмируя полученные ответы: каррирование является неотъемлемой частью того факта, что функции являются "первоклассными" гражданами, то есть объектами, которые могут быть созданы и переданы, как и любые другие ссылки на объекты. Это позволяет возвращать функцию из функции, другими словами каррирование.

Что касается причины, по которой каррирование полезно, каррирование предоставляет синтаксис, позволяющий кратко декорировать вызовы функций, чтобы производные функции могли быть созданы с минимальными накладными расходами на шаблонный код. В то время как в java вы можете создать несколько перегруженных или «оберточных» методов для каждого частичного набора параметров, которые в конечном итоге вызывают главный метод, содержащий все параметры, каррирование обеспечивает более легкий синтаксис, который позволяет вам генерировать эти «функциональные обертки» по мере необходимости в вашем коде.


person Magnus    schedule 17.03.2012    source источник
comment
Я не знаю, что это лучше (кроме академического), это просто часть другого образа мыслей о проблемах. Каррирование, наряду с другими функциональными идиомами, действительно позволяет опытному программисту кратко изложить идею, не жертвуя выразительностью.   -  person jpm    schedule 17.03.2012
comment
Вы можете проголосовать, принять или прокомментировать эти ответы.   -  person Marcin    schedule 20.03.2012
comment
@Marcin: Я попросил привести пример того, как каррирование делает то, чего не может обратный вызов. Все еще жду этого ...   -  person Magnus    schedule 27.03.2012
comment
@Magnus Обеспечивает ли обратный вызов частичное приложение? Нет? Вот твой пример. А теперь не могли бы вы привести мне пример того, что может сделать чили, чего нет в машине?   -  person Marcin    schedule 27.03.2012
comment
@Marcin: Приведенная вами тавтология, очевидно, не очень информативна ... Я надеялся на искренний пример, демонстрирующий сценарий программирования, демонстрирующий уникальную полезность каррирования таким образом, который нелегко эмулировать стандартными существующими методами Java, такими как обратные вызовы и перегрузка. Например, частичное приложение кажется мне очень похожим на перегруженный метод, который связан с другими версиями метода. Ввиду отсутствия значимых примеров я вынужден заключить, что каррирование - это скорее удобство, чем необходимость. Вы бы согласились?   -  person Magnus    schedule 27.03.2012
comment
@Magnus Позвольте мне задать вам вопрос: как бы вы имитировали каррирование с помощью обратного вызова? Вы не можете. Вот чем они отличаются. Что касается x для удобства, вы можете сказать то же самое о буквально любой функции на любом языке, не ограничиваясь только функциями, необходимыми для достижения эквивалентности по Тьюрингу. Еще раз, я не думаю, что вы понимаете, что такое каррирование или частичное приложение. Они совсем не похожи на обратные вызовы или перегруженные методы.   -  person Marcin    schedule 27.03.2012
comment
@Marcin: Дело не в том, что каррирование и обратные вызовы - одно и то же, дело в том, что варианты использования этих методов, похоже, пересекаются. Всякий раз, когда я спрашиваю, для чего подходит каррирование, я получаю такие же ответы, как и ваш, о том, что его можно использовать для создания механизма, который действует как обратный вызов. Итак, перефразируя мой вопрос, каков еще один вариант использования каррирования, который отличается от варианта использования обратного вызова?   -  person Magnus    schedule 27.03.2012
comment
@Magnus Этот вариант использования такой же, как и для частичного приложения, потому что это форма частичного приложения. У вас есть универсальная функция, и вы хотите, чтобы она выполняла что-то конкретное. Можете ли вы сделать это с помощью обратного вызова?   -  person Marcin    schedule 27.03.2012
comment
@Marcin: Понятно, поэтому он полезен как оболочка для функции. Согласны, что это больше не похоже на обратный вызов, теперь это похоже на метод-оболочку. Итак, суть, которую я получаю, такова: каррирование предоставляет синтаксис, позволяющий лаконично декорировать вызовы функций, чтобы производные функции могли быть созданы с минимальными накладными расходами на шаблонный код. Это звучит точно? И он полный, или есть другие варианты использования?   -  person Magnus    schedule 28.03.2012
comment
@Magnus Да, вы поняли, как они работают. Это все, что есть как таковое, но, конечно же, дело в том, что это одна из функций, обеспечивающих очень лаконичный стиль программирования.   -  person Marcin    schedule 28.03.2012


Ответы (2)


Ну это вопрос языковой поддержки. В Java, например, вы можете определить все виды интерфейсов обратного вызова: один для методов без параметров, один для методов с одним аргументом, один для методов с двумя аргументами и так далее.

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

interface Fun<A,B> {
    public B apply(A a);
}

или тому подобное, что покрывает этот образец.

person Ingo    schedule 17.03.2012

Каррирование и обратные вызовы - две совершенно разные технологии.

Обратные вызовы по сути являются синонимом «передачи функции в функцию» (то есть функции более высокого порядка, которая использует функцию); каррирование - это форма частичного применения, то есть функция, которой не переданы все ожидаемые параметры, возвращает новую функцию, которая ожидает только свободные параметры.

Соответственно, они вообще не альтернативы.

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

person Marcin    schedule 19.03.2012
comment
Для меня это все еще довольно абстрактно. Возможность сделать частичную функцию, которая выполняет обратный вызов для каждого элемента на карте, кажется стандартным шаблоном посетителя, который немного упрощается за счет того, что функции Scala являются объектами первого класса, но все же легко эмулируются с помощью анонимных классов Java. Что еще мне не хватает? Может быть, это влияет на параллельную производительность или гибкость методов компиляции? - person Magnus; 23.03.2012
comment
@Magnus Частично примененная функция не выполняет обратный вызов. Повторяйте это, пока не вспомните. - person Marcin; 23.03.2012
comment
@Magnus Вы серьезно запутались. Как вы думаете, какова связь между каррированной (или частично применяемой) функцией и обратным вызовом? - person Marcin; 23.03.2012
comment
конечно я в замешательстве, поэтому не торопился задать вопрос по SO. Re: связь, которую я вижу между каррированием и обратным вызовом - вы только что использовали слово обратный вызов 3 раза в своем описании того, как используются каррированные функции, нечестно притворяться, что это полностью несвязанные концепции. Если дать мне петь мантру, это тоже не поможет осветить разницу. - person Magnus; 27.03.2012
comment
@Magnus Я вообще не использую слово callback при описании каррирования. Я описываю, как каррирование - это удобный способ создания функции, которая может использоваться как обратный вызов. Судя по вашему аргументу, все функции похожи на обратные вызовы. - person Marcin; 27.03.2012