Каковы преимущества и недостатки в подходах C #, Java и Scala к Closures /Lambdas /...?

Интересно, каковы различия в технической реализации между C # и Scala и как оба решения сравниваются с идеями и проблемами реализации, озвученными в письме Проект Lambda (JSR 335) ?

Из письма:

  

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

и далее:

  

Лямбда-объекты-объекты зрения мира конфликтуют с этим возможным   будущее. В представлении лямбда-функций вид мира нет, и   сохранение этой гибкости является одним из   обременяя лямбды даже при появлении объективности.

Вывод:

  

Lambdas-are-functions открывает двери. Объекты Лямбдаса закрывают их.
  Мы предпочитаем видеть, что эти двери остаются открытыми.

И какой-то комментарий от человека в потоке Reddit говорит:

  

Я действительно отправил по электронной почте Нила Гафтера об этом и моих ограниченных   понимание его объяснения C # и текущего Java-дизайна   очень похоже на то, что делегаты на самом деле являются объектами, а не функциями   типы. Похоже, он полагает, что Java должен учиться на   недостатки лямбда C # и избежать их (как и C #   от недостатков Java и избегали их в начале).

Почему подход «Lambdas-are-functions» дает больше возможностей в будущем, чем «Lambdas-are-objects»? Может кто-нибудь объяснить, какие различия существуют и как они повлияют на то, как будет написан код?

Увидев, что вещи в Scala «просто работают», я продолжаю думать, что мне что-то не хватает в подходах, принятых /предложенных в C # /Java (8), возможно, это связано с опасениями о обратной совместимости?

30 голосов | спросил soc 19 PM00000040000003931 2011, 16:12:39

3 ответа


15

Я думаю, что обсуждение объектов против функций - это красная селедка. Если возникает вопрос: «Является ли лямбда функцией или объектом?» ответ должен быть да .

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

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

ответил Rex Kerr 19 PM00000060000004931 2011, 18:48:49
9

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

  

Вы можете подумать, что текущий дизайн тесно связан с полем объекта   для lambdas - типы SAM - что делает их эффективно объектами в любом случае. Но   это было тщательно скрыто от поверхности, чтобы позволить нам   рассматривать «голые» лямбды в будущем или рассматривать другую конверсию   контекстов для лямбда, или более тесно интегрировать лямбда   строит. Мы не делаем этого сейчас, и у нас даже нет конкретного   план для этого, но способность, возможно, сделать это в будущем   критическая часть дизайна.

Я думаю, что подводит итог вашему вопросу довольно хорошо. Если вы объявляете, что «лямбды - это объекты», то они просто объект определенного класса, и вы застряли в этом. С другой стороны, если вы объявляете «lambdas are functions», то semantically у вас гораздо более богатое игровое поле. Java 1.7 может скомпилировать их для объектов, поэтому они практически идентичны в этой точке.

Но Java 1.8 или 1.9 могут вносить изменения в язык (например, структурные типы reified), чем использовать функции, которые будут использоваться более гибкими способами. Если «лямбды были объектами», эти изменения не будут обратно совместимы, и вам придется вводить новую концепцию altogther, чтобы не нарушать существующий код людей. Но если javac просто тихо конвертировал lambdas в объекты за кулисами, новый javac может преобразовывать их во все, что захочет, до тех пор, пока семантика сохраняется.

ответил Andrzej Doyle 19 PM00000040000005131 2011, 16:26:51
5

В основном, он просто не хочет слишком рано совершать что-то. Я не вижу никакой причины, кроме стирания, которую он представил, но это действительно очень сильная причина.

  

Мне не нравятся типы функций - я люблю типы функций, но это   типы функций плохо сражались с существующим аспектом типа Java   система, стирание. Стираемые типы функций являются наихудшими из обоих миров.

Рассмотрим эти методы в Regex:

def replaceAllIn (target: CharSequence, replacer: (Match) ⇒ String): String
def replaceSomeIn (target: CharSequence, replacer: (Match) ⇒ Option[String]): String

Было бы проще, если бы они были просто такими:

def replace (target: CharSequence, replacer: (Match) ⇒ String): String
def replace (target: CharSequence, replacer: (Match) ⇒ Option[String]): String

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

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

def replaceAllIn (target: CharSequence, replacer: (String) ⇒ String): String
def replaceAllIn (target: CharSequence, replacer: (Seq[String]) ⇒ String): String
def replaceAllIn (target: CharSequence, replacer: (Match) ⇒ String): String

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

И тогда подумайте, что соответствие шаблона Scala и код instanceof Java бесполезны из-за стирания.

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

ответил Daniel C. Sobral 20 AM00000010000000431 2011, 01:20:04

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132