Причини видалення типів функцій на Java 8


12

Я намагаюся зрозуміти, чому експертна група JDK 8 Lambda (EG) вирішила не включати новий тип функції в мову програмування Java.

Переходячи над списком розсилки, я знайшов нитку з дискусією про видалення типів функцій .

Багато тверджень для мене неоднозначні, можливо, через відсутність контексту, а в деяких випадках через мої обмежені знання щодо впровадження типних систем.

Однак є кілька питань, які, на мою думку, я можу сміливо сформулювати на цьому веб-сайті, щоб допомогти мені зрозуміти, що вони мали на увазі.

Я знаю, що міг би задати питання у списку розсилки, але нитка стара і всі рішення вже прийняті, тому є ймовірність, що мене проігнорують, перш за все бачачи, що ці хлопці вже затримуються зі своїми планами.

У своїй відповіді на підтримку видалення типів функцій та схвалення використання типів SAM Брайан Гец говорить:

Немає вдосконалень. Існував довгий потік про те, наскільки корисним було б переформатування типів функцій. Без внесення змін, типи функцій сплющуються.

Я не зміг знайти нитку, яку він згадує. Тепер я можу зрозуміти, що впровадження структурного типу функцій може спричинити певні ускладнення в системі Java здебільшого номінального типу, що я не можу зрозуміти, наскільки параметризовані типи SAM відрізняються за зміною.

Чи не є вони обома проблемами вдосконалення? Хтось розуміє, наскільки типи функцій відрізняються від параметризованих типів SAM з точки зору переробки?

В іншому коментарі Гец говорить:

Існує два основних підходи до введення тексту: номінальний та структурний. Ідентифікація номіналу заснована на його назві; ідентичність структурного типу заснована на тому, з чого він складається (наприклад, "кортеж int, int" або "функція від int до float".) Більшість мов вибирають переважно номінальну або переважно структурну; Є не так багато мов, які успішно поєднують номінальну та структурну введення, за винятком "навколо країв". Java майже цілком номінальна (за кількома винятками: масиви є структурним типом, але внизу завжди є номінальний тип елементів; у загальних рисах також є суміш іменних і структурних, і це фактично є частиною джерела багатьох скарг людей на дженерики.) Перенесення системи структурних типів (типів функцій) на Java ' Система номінального типу означає нові складності та крайні корпуси. Чи варто того виду функцій?

Ті з вас, які мають досвід впровадження систем типу. Чи знаєте ви якісь приклади цих складностей чи крайових випадків, про які він згадує тут?

Чесно кажучи, я плутаюсь у цих твердженнях, коли вважаю, що мова програмування на зразок Scala, яка повністю базується на JVM, має підтримку структурних типів, таких як функції та кортежі, навіть із проблемами переробки основної платформи.

Не зрозумійте мене неправильно, я не кажу, що тип функції повинен бути кращим, ніж типи SAM. Я просто хочу зрозуміти, чому вони прийняли таке рішення.


4
"Перенесення системи структурних типів (типів функцій) на систему номінального типу Java означає нову складність" - це, швидше за все, означалося як складність для користувачів, які повинні навчитися більше користуватися мовою . Щось на кшталт простої та простої у використанні Java стає схожою на складні та важкі для вивчення C ++ , подібні речі. Члени списку розсилки, ймовірно , можуть посилатися на критику раніше «великої хвилі поліпшень», один з яскравих прикладів є Java 5 відстоєм статті Клінтон почала MyBatis
комар

3
"Проста та зручна у використанні Java стає схожа на складну та важко вивчену C ++": На жаль, одна проблема з основними мовами програмування полягає в тому, що вони повинні зберігати зворотну сумісність, і тому вони, як правило, стають занадто складними. Тож у IMHO (маючи багаторічний досвід роботи як з C ++, так і з Java) є щось справжнє в цьому твердженні. У мене часто виникає відчуття, що Java повинна бути заморожена, а замість неї розробити нову мову. Але Oracle не може ризикувати.
Джорджіо

4
@edalorzo: Як показали Clojure, Groovy, Scala та інші мови, можна (1) визначити нову мову (2) використовувати все багатство бібліотек та інструментів, які вже написані на Java, не порушуючи зворотної сумісності (3) Java-програмісти можуть вибирати, чи хочуть вони залишитися з Java, перейти на іншу мову чи використовувати обидва. IMO, нескінченно розширювати існуючу мову - це стратегія для утримання клієнтів так само, як компаніям мобільних телефонів потрібно постійно створювати нові моделі.
Джорджо

2
Як я зрозумів з SAMbdas на Java , одна з причин полягає в тому, що було б проблематично підтримувати сумісність деяких бібліотек (колекцій).
Петро Пудлак

2
Пов’язана публікація на SO, яка посилається на цю іншу публікацію Геца .
assylias

Відповіді:


6

Підхід SAM насправді дещо схожий на те, що Scala (і C ++ 11) роблять з анонімними функціями (створеними за допомогою =>оператора Scala або []()синтаксису C ++ 11's (лямбда)).

Перше питання, на яке потрібно відповісти на стороні Java, - чи мати тип повернення оператора lambda бути новим типом primitve, як intабо byte, або тип об'єкта якогось типу. В Scala, там немає жодного примітивного типу - навіть ціле число є об'єктом класу Int- і функція не відрізняється, що є об'єктами класу Function1, Function2і так далі, в залежності від кількості аргументів функції приймає.

C ++ 11, рубін і пітон так само мають лямбда-вирази, які повертають об'єкт, який можна викликати явно або неявно. Повертається об'єкт має деякий стандартний метод (наприклад, #callякий можна використовувати для виклику його як функції. Наприклад, C ++ 11 використовує std::functionтип, який перевантажує operator()так, що виклики методу виклику об'єкта навіть виглядають як текстові виклики, текстуально. :-)

Там, де нова пропозиція для Java стає безладною, полягає у використанні структурного набору тексту, щоб дозволити призначити такий метод іншому об'єкту, наприклад, у Comparatorякого є єдиний основний метод з іншою назвою . Хоча це концептуально непривабливе в деякому сенсі, це робить означає , що отриманий об'єкт може бути переданий в існуючі функції , які приймають об'єкт для подання на зворотний дзвінок, компаратора, і так далі, і очікувати , щоб бути в змозі назвати цілком певний сингл такий спосіб, як #compareабо #callback. Трюк C ++ operator()акуратно ухилився від цього питання ще до C ++ 11, оскільки всі такі варіанти зворотного виклику можна дзвонити однаково, і, таким чином, STL не потребував коригування, щоб дозволити використовувати C ++ 11 лямбда зsortі так далі. Java, що раніше не використовувала стандартні імена для таких об'єктів (можливо, тому, що жоден фокус, як перевантаження оператора, не зробив очевидним єдиний підхід), не так пощастило, тому цей хакер заважає їм змінювати цілу партію існуючих API .


1
За іронією долі, проблеми, якщо мати безліч різних, несумісних типів, усі вони представляють собою якусь "функціональну річ", можна було б акуратно уникнути, додавши стандартні типи функцій до бібліотеки на початку, незалежно від фактичного буквального синтаксису для їх побудови. Якби java.util.Function2<T1, T2, R>у Java 1.0 був Comparatorінтерфейс, то інтерфейсу не було б , натомість усі ці методи брали б a Function2<T1, T2, int>. (Ну, був би цілий ряд інтерфейсів, таких як Function2TT_int<T1, T2>примітиви, але ви розумієте.)
Jörg W Mittag
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.