Я начал серьезно смотреть на Lisp в эти выходные (я имею в виду, что изучал только Lisp и не возвращаюсь к проектам на C #) и должен сказать, что мне это нравится. Я баловался с другими функциональными языками (F #, Haskell, Erlang), но не чувствовал ничьей, которую дал мне Лисп.
Теперь, когда я продолжаю изучать Lisp, я начал задаваться вопросом, почему нефункциональные языки не поддерживают первоклассные функции. Я знаю, что языки, такие как C #, могут делать аналогичные вещи с делегатами, и в какой-то степени вы можете использовать указатели на функции в C / C ++, но есть ли причина, по которой это никогда не станет функцией в этих языках? Есть ли недостаток в создании функций первого класса? Для меня это чрезвычайно полезно, поэтому я заблудился, почему больше языков (за пределами функциональной парадигмы) не реализуют его.
[Редактировать] Я ценю ответы до сих пор. Поскольку мне было показано, что многие языки теперь поддерживают первоклассные функции, я перефразирую вопрос: почему языкам потребуется так много времени для их реализации? [/Редактировать]
Ответы:
C #, VB.NET, Python, JavaScript, теперь даже C ++ 0x предоставляет первоклассные функции.
Обновить:
Реализация замыканий требует лямбда-лифтинга - техники, изначально совершенно чуждой для императивных программистов. Правильные первоклассные функции (которые включают замыкания) требуют, по крайней мере, некоторой поддержки со стороны времени выполнения и виртуальной машины. Также потребовалось некоторое время, чтобы перенести старые функциональные методы в императивный мир.
И самая важная часть - первоклассные функции едва ли можно использовать, если отсутствует сборщик мусора. Он был внедрен в массовое программирование только недавно, с Java и, следовательно, .NET. И оригинальный Java-подход заключался в том, чтобы упростить язык, чтобы его могли понять обычные программисты. Сначала последовал .NET, и только недавно расстался с этим (ИМХО, вполне оправданным и уместным) направлением.
Все такие концепции требуют времени для усвоения промышленностью.
источник
Первоклассные функции намного менее интересны без замыканий.
Замыкания на самом деле невозможны без какого-либо динамического управления областью действия (сборкой мусора). Одна из вещей, которая делает C / C ++ настолько высокопроизводительным, заключается в том, что намного проще скомпилировать язык, в котором вы управляете памятью вручную, так что это своего рода выводит C / C ++ из уравнения.
И тогда да, есть вопрос влияния ООП. У вас больше нет разделения методов и свойств. Методы сами по себе являются свойствами, которые принимают функции в качестве значений. В этом контексте, что на самом деле означает перегружать методы, так как вы можете просто поменять глупые вещи в любое время. Можете ли вы добавить это к Java, например, не вводя основной сдвиг парадигмы для всего языка? Где контракт или это чувство (IMO-ложь) безопасности, которое люди получают, зная, что конструкция гарантирует, что она всегда будет работать одинаково каждый раз? Возможно, имеет смысл рассматривать функции, привязанные к объектам, как методы как отдельный организм в языках, которые вначале позволяли функциям существовать независимо, но в Java это на самом деле не вариант.
В JavaScript ООП и функционал очень тесно переплетены, и мне лично было бы трудно увидеть первоклассные функции как что-то еще, кроме как в языках, где их не было. Но это требует ряда других изменений, меняющих парадигму, включая высокий уровень изменчивости объектов и самих их методов, а также возможность вызова функций, как если бы они были членами любого объекта на лету.
Языки - это не просто наборы инструментов, полные do-hickeys для достижения цели по большей части. Они парадигмы. Связки идей, стратегий и мнений, которые все вместе сочетаются (или кажутся связанными). Во многих случаях такие функции, как существительное и глагол, на самом деле просто не соответствуют парадигме или, в лучшем случае, несовершенные.
Тем не менее, я чувствую, что мне не хватает руки, когда вынуждены кодировать без них.
источник
Это не совсем невозможно. Но это еще одна особенность, а бюджет сложности ограничен. Разработчик языка может счесть ненужным (или даже не подозревать об этом) - «какого черта нам нужно передавать функции? Этот язык предназначен для программирования ОС!». Может также потребоваться значительное усилие, чтобы слиться с остальной частью языка. Например, тип функции может потребовать серьезных дополнений к системе типов (например, в Java), даже больше, если у вас есть перегрузка (спасибо @Renesis за указание на это). Вы также должны предоставить некоторый библиотечный код для использования жизнеспособных - никто не хочет определять
map
себя.Это также может затруднить достижение других целей языка:
f
никогда не переназначаются, прежде чем встроить их.В том же духе можно спросить, почему любой язык программирования L1 не имеет функции F совершенно другого языка L2.
источник
Я думаю, что первая проблема - это неправильное понимание того, что объектно-ориентированное и функциональное невозможно смешать. Краткий список языков, описанных, по крайней мере в Википедии, как: JavaScript , ActionScript , Python , C # , F # .
Вторая проблема, по-видимому, заключается в определении функций первого класса - почему вы не считаете, что в C # они есть, например?
Я не эксперт по функциональному языку, поэтому, пожалуйста, исправьте меня в комментариях, если я ошибаюсь, но я понимаю, что включение первоклассных функций более или менее определяет, поддерживает ли язык функциональную парадигму .
Какой реальный вопрос?
Итак, понимание того, что объектно-ориентированные языки также могут быть функциональными, и эти языки содержат функции первого класса, звучит так, как будто вы ищете вопрос: почему некоторые объектно-ориентированные языки не содержат функций первого класса?
Перегрузка функций
Одной из основных причин этого является сложность определения функций первого класса, когда язык также решил поддерживать перегрузку функций (пример в Java):
К какой
dispatchEvent
функции будет относиться переменная?Программирование на основе классов
Программирование на основе классов не мешает языкам поддерживать первоклассные объекты, но может сделать его более запутанным или добавить вопросы для ответа.
Например, ActionScript как язык ECMAScript начинался с гораздо более функциональной парадигмы, такой как JavaScript. Функции не были изначально связаны с объектами, их можно было вызывать с любым объектом, так как это область действия во время выполнения.
Когда вы добавляете (не динамические) классы, у вас есть функции, которые неотъемлемо связаны с экземпляром, а не только с самим классом. Это приводит к появлению нескольких складок в спецификации,
Function.apply
которую я, честно говоря, не зарыл, чтобы узнать, как они справились с этим.источник
Я сам удивлялся тому же самому. Как только я нахожусь на языке с лямбдами, я использую их МНОГО. Даже PHP становится лучше, когда вы понимаете, что вы можете сделать замыкание с помощью php 5.3 (это не так хорошо, как lisp, но все же лучше)
источник