Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Копипаст или ноу-хау джавы

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Из ветки
dou.ua/...​forums/topic/6596/#276484
Составил список того что в джаве, на мой взгляд, является чем-то новым. Возможно не революционным, но привнесло новые вещи на уровне концепций
dou.ua/...​forums/topic/6596/#276490
Краткий список:

— Дженерики (на мой взгляд, концептуально отличаются от шаблонов в том же ЦПП).
— Дефендеры (на мой взгляд, концептуально отличаются от примесей и тд).
— Лямбды (точнее джава-лямбды, которые, на мой взгляд, существенно концептуально отличаются от реализации в других языках).
— Классы уровня экземпляра (Non-Static/Inner Classes, не Nested Classes). Сходу не смог вспомнить где еще есть такое.
— Аннотации, в том числе и пользовательские.
— Джавадок (это минорное).

Посему вопрос:
Были ли эти вещи ранее? Если да, то в каких языках?

Уточнение:
Не просто что-то похожее, а такое же на концептуальном уровне.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

без примеров статья ничего не значит. просто набор слов. набор умных слов, многое из которых мне ничего не говорят. и я уверен, что не одному мне. алсо, если пошла речь об лямбдах — чем они концептуально отличаются от анонимных классов, реализующих интерфейс Calable и ему подобных?

без примеров статья ничего не значит.

Какая статья?

dou.ua/...ums/topic/6728

msangel, на форумах (forums) пишут торики/посты (topic), а не статьи :) У вас есть еще один прекрасный повод для самообразования, кроме:
слов, многое из которых мне ничего не говорят

об лямбдах — чем они концептуально отличаются от анонимных классов, реализующих интерфейс Calable и ему подобных?

Интересно глянуть, как на джаве будет выглядеть подобный код:

public static Func<dynamic> Invert(this Func<dynamic> fact)
{
return () => new { Left = fact().Right, Right = fact().Left };
}

Интересно глянуть, как на джаве будет выглядеть подобный код:

Ну так посмотрите если вам интересно. Данная тема не про то у кого длиннее.

Если бы было действительно интересно узнать — не поленился бы наверное объяснить что этот код делает. Тогда может и покажем. Пока, based on many assumptions, в редакторе выглядит так:

public static <l,r,o> Func<r,l,o> invert(final Func<l,r,o> fact) { return (left,right) -> { return fact.apply(right, left); }; }

с форматирование кода в ДОУ не справился :)

public static <l,r,o> Func<r,l,o> invert(final Func<l,r,o> fact) { return (left,right) -> { return fact.apply(right, left); }; }
Сомнивательно. Скорее всего человек намекает на “выведение типов” и “анонимные типы”.

Тут метод расширения, динамический тип, анонимный тип, делегат и лямбда.

это просто функция (метод), который принимает функцию и возвращает функцию. Принимаемая функция — Func<dynamic> fact — имеет ноль аргументов и возвращает динамический объект. Результат функция Invert — это функция, которая позволит вычислить «перевернутый» объект (объект в котором Left и Right поменяны местами). Декларативный стиль — вычисление не происходит, просто возвращается функция.

Это я на днях пытался сишарп абьюзить — полную версию кода можно глянуть на github.com/...onCsharpFPStyle

а, извращения... я было думал что-то полезное :)

Это я на днях пытался сишарп абьюзить

Вот это — то как не надо юзать Шарп. Всё по отдельности полезно, но вместе образует гремучую смесь.

зато я узнал об ограничении сишарпа — cannot assign ’lambda expression’ to anonymous type property. Т.е. нельзя вернуть анонимный объект с анонимной функцией ;)

Т.е. нельзя вернуть анонимный объект с анонимной функцией ;)

Стоп. Для прояснения ситуации:
Возможно ли в Ц№ создавать «Анонимный тип» с методами?

Я думал что там только плайн-обджект и тот с неизменяемыми полями. (Это к пункту про Иннер и Нестед классы)

можна с делегатами, но сообсвенно без референса на обєкт

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

Код на си шарпе никак не будет на джаве выглядеть.

Для реализации подобного функционала джава использует джавовские фичи.

Для реализации подобного функционала джава использует джавовские фичи.
А как повторить анонимные типы? Сходу придумать не могу, развешо типа много дженерик кортежей.
еще раз: не надо их повторять
заказчик просит не аномимные типы, а чтоб кнопка работала

К.Ф. предлагает перевести в английской книге каждое отдельное слово на русский — ясно, что получится какашка.

В дотнете это все было еще в версии 3.5
Ну разве что Дефендеры...

Да и вобще что оно такое? может оно и есть а я не знаю что это Дефендер?

Как я понял, это аналог Extension Method в сишарпе

Как я понял, это аналог Extension Method в сишарпе
Где-то такой же как и миксинов :)

+ Checked Exceptions. Сильная selling point поначалу и провалившийся эксперимент походу.

+ Checked Exceptions.

Не был уверен, думал что они были в «эзотерических языках» ранее.

эзотерика в сад. Копикатом не считается пока не реализовано в языке имеющим хоть сколько видимое наличие в реальном использовании. А вообще топик странный. Хороший копикат в мейнстрим лучше и важнее любой эзотерики.

зачем вообще все это надо?
как по мне выглядит сие следующим образом — сначало откинули многое по сравнению с другими языками, в силу различных причин. а теперь пытаются добавлять некие «work-around» дабы частично вернуть выкинутое ранее.

ну и опять таки, зачем все это надо?

посмотрите даты выхода аналогичних фишок шарпе(C#) - больше половины описаного там было раньше, хоть и не обязательно — впервые

тогда уж не даты выхода сравнивать, а даты подачи JCP на общее рассмотрение, в джаве некоторые фишки годами ждут своего релиза

шарпе(C#) - больше половины описаного там было раньше

Так вы и посмотрите и скажите?
Дженерики, джавадоки, аннотатции (пользовательских вроде бы нет) появились позже.
Внутренних классов нет (не путать с нестед).
Дефендеров нет (в джаве только в бетте).

«Функциональных интерфейсов» нет (лямбда — это надстройка над делегатом, а не над классом)

Если ошибаюсь, то укажите где.

аттрибуты(C#) - January 2002 (v1.0, пользовательские есть как минимум с v1.1)
аннотации(java) — September 2004(v1.5)

дженерики(C#) - November 2005 (v2.0)
дженерики(java) — September 2004(v1.5)

джавадоки и хмл-коменты есть с первых версий, тут у джавы с 10 лет форы

внутринние класы — в шарпе все нестед класы имеют доступ к приватым мемберам парента — с версии 1.0 — January 2002

дефендеры(Java) — expected in September 2013(v8)
екстеншин методы(C#) - November 2007(v3.0)
(насколько я понял из короткого гайда по дефендерам, идется сообственно про аналог екстеншн методов)

лямбда(Java) — expected in September 2013(v8)
лямбда(C#) - November 2007(v3.0)
— явления идентичные

Если ошибаюсь, то укажите где.
;)

аттрибуты

Принято.

дженерики

Ну таки в шарпе на год позже :)

джавадоки

Таки на 10 лет позже (хотя вроде таки на 5)

нутринние класы — в шарпе все нестед класы имеют доступ к приватым мемберам парента — с версии 1.0 — January 2002

en.wikipedia.org/...y_19.2C_1997.29

Основной поинт был как раз не про нестед, а иннер классы en.wikipedia.org/...f_inner_classes которых в шарпе нет.

(насколько я понял из короткого гайда по дефендерам, идется сообственно про аналог екстеншн методов)

Где-то такой же как и миксинов. :) На уровне концепци отличаются. ИМХО, екстеншин методы сильно отличаются, так как по факту позволяют послать сообщение нулл-у, позволяют подключать разные неймспейсы (разные реализации в разных частях программы). То есть механизм со своими неоднозначностями.

лямбда(Java) — expected in September 2013(v8)

лямбда(C#) - November 2007(v3.0)

лямбда — это надстройка над делегатом, а не над классом

не про нестед, а иннер классы

they can implicitly refer to instance variables and methods of the enclosing class. — во всех описаниях иннер класов джавы упоминается как ключевая фишка иннер класов — доступна всем нестедам в шарпе

аналоги мембер и анонимных подвидов иннеров есть в шарпе с ~2007го, локальных нету

лямбды:
чем ето:
forEachEntry(map, {
Integer key, String value =>

System.out.println(key + “: ” + value); });

отличается от
list.Each(item => {Console.WriteLine(item.name)});
??

и функціонально, и идейно, они идентичные

На уровне концепци отличаются. ИМХО,

на уровне реализации — да, а идея какраз та же — прикрепить к существующим типам и обектам новую функциональность

аналоги мембер и анонимных подвидов иннеров есть в шарпе с ~2007го, локальных нету

Повторите такое:

public class Main {

static class O {
private int f = 100500;
class I {
public int m() {
return f;
}
}
}

public static void main(String[] args) {
final O o = new O();
final O.I i = o.new I();
System.out.println(i.m());//100500
}
}

Важно: гарантировать привязку к интстансу.

public class Sure
{
public static void Main()
{
Parent parent = new Parent();
var child = parent.GetChild();
Console.WriteLine(child.GetParentsId());
}
}
class Parent
{
private int id = 101501;
public Child GetChild()
{
return new Child(this);

}

class Child
{
Parent parent;
public Child(Parent parent)
{
this.parent = parent;
}
public string GetParentsId()
{
return parent.id;
}
}

}

А теперь на уровне языка?

На любом языке можно сделать практически что угодно. Те же лямбды эмулируются анонимными классами.

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

а смысл автоматизировать чтото ище?

Те же лямбды эмулируются анонимными классами.

в версии джавы и одно и другое имеет одну не особо здоровую особенность — упаковку и лямбд и анонимных методов в класы, хоть и там и там метода хватает, и клас в 99% не даст никакого преймущества

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

порвало шаблон
словосточетание «чтото ище» в контексте фразы

«на уровне языка дается доступ к прайват мемберам любого инстанса парент класа»

шаблон должна рвать тяга упрощения и автоматизации редких случаев (1-5%), тогда как средствами языка они просто должны быть реализуемые, а частые варианты(30+%) уже упрощатся и автоматизироваться

шаблон должна рвать тяга упрощения и автоматизации редких случаев (1-5%),

Суть в том что специально никто ничего не «автоматизировал». Дали возможность объявлять классы внутри контекста других классов. Как статического контекста, так и не статического.

да, кстати, с поправкой на то что в вашем примере Parent (O) — статический, все что надо чтоб доступится до его прайват мемберов — его имя —

public string GetParentsId()
{
return Parent.id;

}

— без сохранения референса на парент в чайлде

да, кстати, с поправкой на то что в вашем примере Parent (O) — статический, все что надо чтоб доступится до его прайват мемберов

Скоро НГ и вы в джаве не шарите, посему скажу просто: вы ошибаетесь :)

иннер-сатик классы в джаве — это тоже что нестед классы в шарпе.

аналогично про вас и шарп, тольки я не затрядняюсь при етом перед ответом полазить по нету и найти пару описаний фич и примеров :)

я не затрядняюсь при етом перед ответом полазить по нету и найти пару описаний фич и примеров :)

Рылли

Parent (O) — статический, все что надо чтоб доступится до его прайват мемберов — его имя —
public string GetParentsId()
{
return Parent.id;

}

? :)

здесь мы наблюдаем 2 фичи:
— синтаксический сахар по передаче parent.this — ну хорошо, новшество, пару строчек кода сэкономили

— хромую имплементацию friends из с++ (которая погибче будет, ибо классы необязательно нестить)

— синтаксический сахар по передаче parent.this — ну хорошо, новшество, пару строчек кода сэкономили

Нет. Ключевой момент — это возможность определять класс в контексте объекта.

Возможно ли у Ц№-лямбды вызвать несколько методов?

public interface Block<t> {

public void accept(T t);

public default Block<t> chain(Block other) {
Objects.requireNonNull(other);
return (T t) -> { accept(t); other.accept(t); };
}
}
public class Lambda {

public static void main(String[] args) {
Block<string> b = System.out::println; // Это просто другая запись, не важно

Block<string> b1 = (s) -> {
System.out.println(100500);
};

final Block<string> chain = b.chain(b1); // У лямбды 2 метода и оба можно вызвать
chain.accept("ololo");
}

}

С моей точки зрения, большинство новых фич — это просто костыли под кривизну и ограниченность языка (дефендеры — это как раз костыль вместо mix-in — но относительно элегантный, с этим я согласен — но, как всегда, покрывает только один сценарий, когда расширяет интерфейс автор интерфейса — т.е. если в вашем проекте есть утилита которую вы на каждом шагу используете — вы её в java.util.Collection не добавите, нет, — и дальше помните в каком пакете какой класс её содержит).

Я могу сказать чем меня раздражает Ява:
1. Generic’s
Недошаблоны. Т.е. template programming не сдалать (только типы могут быть аргументом шаблона), instanceof против аргументов шаблона не сделать, new T[] не скажешь. Куча невидимых кастов только...

Отдельно Явовские шаблоны люблю за отсутствие в языке typedef — Map<string, collection<tuple<integer,="" string=«">>> - и все это каждый раз при создании. Спасибо что diamond notation прикрутили, немного полегчало.

2. Лямбды

И опять будет новый .class файл — когда в большинстве случаев все что требуется — передать указатель на функцию.

3. Отсутствие pass-by-value — помнится, был один проект где другая команда написала date picker — который переданную дату менял даже если пользователь Cancel нажимал. Приходилось clone() делать — а поначалу весьма неочевидные баги вылазили.

4. Я люблю const семантику в C++ - когда можно указать что метод не меняет state объекта.

5. До слез не хватает перегрузки операторов. Намного элегантнее и удобочитаемее код выглядит когда можно сказать «Vector a,b,c; c = a + b;»

Тихо cам с собою? Тему читал?

Отсутствие pass-by-value...Приходилось clone() делать — а поначалу весьма неочевидные баги вылазили.

— лучше делайте данные immutable или инкапсулируйте путем чем требовать сомнительный

синтаксический шугар к тому же clone();

До слез не хватает перегрузки операторов. Намного элегантнее и удобочитаемее код выглядит когда можно сказать «Vector a,b,c; c = a + b;»

ммм. Груви? Скала? Саму джаву не трогайте.

3. Отсутствие pass-by-value — помнится, был один проект где другая команда написала date picker — который переданную дату менял даже если пользователь Cancel нажимал. Приходилось clone() делать — а поначалу весьма неочевидные баги вылазили.

Не понял:

Это что в джаве даже такие типы данных как инт и дейттайм по ссылке передаются?

Integer (не путать с int) — immutable и объект. Все объекты передаются по ссылке. Примитивы по значению. Но с точки зрения правильного пользования иммутабл объект работает так же как и примитив.

DateTime — не примитивный тип, в простейшем виде java.util.Date — суть обертка вокруг long миллисекунд с 1970го года. Стандартно мутабельный, отсюда и проблемы при неосторожном использовании.

Поддержу насчет не-RTTI шаблонов и const-нотации. Но остальное несерьезно. Вектор, вероятно, единственный пример, когда перегрузка операторов так логична, а откуда вообще боязнь лишних .class-файлов ? П. 3 — классика, это как C++ ругать за небезопасные указатели. Effective Java читать на ночь.

Вектор, вероятно, единственный пример, когда перегрузка операторов так логична,

Я бы предпочел сам решать — когда «+» имеет смысл а когда — нет. Даты, координаты, суммы денег с валютами, комплексные числа — можно очень много придумать value typeов которым необходимо бы перегрузить операторы. Я уже не говорю о более творческом подходе — всякие деревья и т.д. где можно было бы покомпактнее нотации делать.

Меня больше всего восторгает как автора Явы прямым текстом сказали что их целевая аудитория — слишком тупа для подобных фишек, запутается. И вот все эти годы целевая аудитория доказывает что compareTo офигенски более удобочитаемо чем ’>’

а откуда вообще боязнь лишних .class-файлов

Неаккуратно.

П. 3 — классика, это как C++ ругать за небезопасные указатели.

Ну да. У нас же объектно-ориентированный язык — поэтому int мы передаем по значению, java.util.Date (или Calendar — не помню уже что) — по ссылке.

Я бы предпочел сам решать — когда «+» имеет смысл а когда — нет.

Отбросим чтение спеки. Что должно получится в результате

«Vector a,b,c; c = a + b;»

?

Конкатенация или поэлементная сумма? А если разность векторов? В общем, стандартная критика перегрузки операторов.

Меня больше всего восторгает как автора Явы прямым текстом сказали что их целевая аудитория — слишком тупа для подобных фишек, запутается.

А ссылочку? То что я слышал:
1) Нет возможности заставить всех соблюдать контракты. А не соблюдая контракты, можно накосячить.

2) Операторы — это не ООП (очень не явная посылка сообщения)

И вот все эти годы целевая аудитория доказывает что compareTo офигенски более удобочитаемо чем ’>’

А ссылочку? (Интересно чего там более удобного)

Конкатенация или поэлементная сумма? А если разность векторов?

mathworld.wolfram.com/VectorSum.html
«A vector sum is the result of adding two or more vectors together via vector addition. It is denoted using the normal plus sign, i.e., the vector sum of vectors A, B, and C is written «A + B + C»

А ссылочку?

Я это помню в каких-то учебниках. Но вы отлично всю реторику повторяете.

1) Нет возможности заставить всех соблюдать контракты. А не соблюдая контракты, можно накосячить.

Я же и говорю — Явисты (по мнению авторов Явы) слишком тупы для перегрузки операторов. Конечно, если мы «operator+» назовем «add» — то компилятор проверит чтобы метод делал то, что ожидается, да?

Операторы — это не ООП (очень не явная посылка сообщения)

Ява как ООП язык — старая шутка. Главное же убрать нормальные функции — и жизнь наладится. Более ООП чем java.lang.Math и java.util.Collections не найти.
В ООП языке не должно быть примитивов — все должно быть объектом. В том числе, не должна быть передача «int a» по значению а «MyInteger a» — по ссылке.

А ссылочку? (Интересно чего там более удобного)

Я не знаю. Это вы против перегрузки операторов и за «контракты»

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

Совершенно не понимаю, чем перегрузка операторов не угодила.

Например «+» (и «-»).
— У него есть довольно жесткий контракт:
— симметричность (уже это не очень хорошо ложится на модель сообщений)
— «+» и «-» должны быть обратными друг к другу (со сравнениями все еще интереснее)
— Контектсность. Пример + для векторов может быть как конкатом, так и поэлементным сложением
Не критичное, но ведь красивое средство.

Красиво, часто удобно, хипстерам нравитсо (возможно в 9-ку включат). Но при этом еще одно место где может налажать падаван, а как показывает практика проблематично сразу родитсо и все знать.

— симметричность (уже это не очень хорошо ложится на модель сообщений)

Вы имеете в виду сообщения из каноничного ООП, а ля Смалтолк? Так в Джаве его отродясь не было.

— «+» и «-» должны быть обратными друг к другу (со сравнениями все еще интереснее)

Add() и Sub() по идее тоже. Но мне никто не помешает сделать их несиметричными.

— Контектсность. Пример + для векторов может быть как конкатом, так и поэлементным сложением

Ну это натянуто. Полагаю, большинство людей воспримет их как сложение. Но даже если и нет:
Add() и Sub() по идее тоже. Но мне никто не помешает сделать их несиметричными.

Красиво, часто удобно, хипстерам нравитсо (возможно в 9-ку включат). Но при этом еще одно место где может налажать падаван, а как показывает практика проблематично сразу родитсо и все знать.

В Шарпе перегрузка есть с самого начала, но падаваны её не используют. С какой стати в Джаве будет не так?

Вы имеете в виду сообщения из каноничного ООП, а ля Смалтолк? Так в Джаве его отродясь не было.

Не путайте «расово верное» и «содержит концепцию». Посылка сообщений в джаве есть, реализовано через методы. Но суть не в этом, суть в том что «+» это не «add(x)», а «sum(x, y)» («add(x)» — это скорее «+=»), для начала. Дополнительный бонус: «null.add(x)» и «x.add(null)», немного не вписываются в симметричность. По этому поводу хороший пример — большинство наездов на javascript, только там на вызовы методов еще и наложились касты вместо явного выброса ошибки о несовместимых типах.
Add() и Sub() по идее тоже. Но мне никто не помешает сделать их несиметричными.

А какой у них контракт? Их контракт определяется интерфейсом где они определены.
Механизм методов, вам позволяет, например, явно запретить перегрузку Sub и реализовать его через Add, то есть operator- operator+. Но в таком случае операторы — это просто «синтаксический сахар» + необходимость помнить то что может быть просто записано в интерфейсе (на сколько помню ни в Ц№, ни в ЦПП операторы не вынесены в интерфейс, и даже не неявно определены в «корневом объекте», а просто сущности)
Второй момент. Надо правильно называть методы, а операторы какбэ уже названы.
В Шарпе перегрузка есть с самого начала, но падаваны её не используют.

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

Посылка сообщений в джаве есть, реализовано через методы.

Коим боком? Вот я с Object C пару лет назад игрался — там я могу послать любое сообщение объекту. И даже корректно отработать незнакомые сообщения. А в Яве несуществующие методы компилятор не пропустит.
Побочный результат — не надо интроспекцию кода делать когда датабиндинг реализуешь. Быстрее работает.

Коим боком?

Методы — это подмножество посылки сообщений. Повторюсь:
Не путайте «расово верное» и «содержит концепцию».

Методы — это подмножество посылки сообщений. Повторюсь:

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

Кстати, в Objective C (как я понял, самый прямой наследник Smalltalk из менстримных языков) сообщение можно и nilу послать. А вам слабо? Или NullPointerException будет потому что таблички не найти?

Кстати, в Objective C (как я понял, самый прямой наследник Smalltalk из менстримных языков) сообщение можно и nilу послать.

А в смолтоке низя, напрямую, но можно настроить обработку исключения.

А вам слабо?

Рефлексия, прокси-шмокси.
Повторяю:

Не путайте «расово верное» и «содержит концепцию».

— «+» и «-» должны быть обратными друг к другу (со сравнениями все еще интереснее)

Умножение тоже? Перед ответом подумайте.

Умножение тоже? Перед ответом подумайте.

То-то же. С интерфейсами (классами) все однозначнее, не надо придумывать и догадываться.

То-то же. С интерфейсами (классами) все однозначнее, не надо придумывать и догадываться

Ответьте на вопрос. Умножение должно быть обратимым друг к другу. У него такой «контракт»?

Умножение должно быть обратимым друг к другу.

Симметричным? Вроде нет.
Или вы про взаимо-обратность, тогда точно нет.
К слову с методом «mul(a, b)», таких непоняток нет ибо его спецификация указана в конкретном интерфейсе и ее не соблюдение — это баг.

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

Меня больше всего восторгает как автора Явы прямым текстом сказали что их целевая аудитория — слишком тупа для подобных фишек, запутается.
 и я, будучи нетупым java developer, с этим полностью согласен.

А что толку обсуждать новшества самого языка ?

Ведь прикол не в самом новшестве, а в удачной реализации и применимости фич.

Ведь прикол не в самом новшестве, а в удачной реализации и применимости фич.

Удачное применение подразумевает изменение (уточнение) общей концепции. Пример, те же джененрики, обобщенное программирование явно не джаве впервые появилось.

Ну я немного не о том. Множна всматриваться в историю, и смотреть были ли языки с похожими реализациями похожих концепций, и насколько фича данного языка самодостоточна и «новаторская». Чем вы и придлагаете заняццо :-)
Но новаторство (на языковом уровне) не всегда для языка полезны. Гораздо полезнее удачный инжениринг и совмецение уже испытанных и проверенных идей. Имхо жаба, какраз в этом направлении и пыталась двигаться, и двигается. А чистое новаторство оно для скалы, хацкеля, немерле, языке агда и прочей «неиспользуемой гомосятины».

Чем вы и придлагаете заняццо :-)

Вообще-то мне просто стало интересно где есть похожие/такие же концепции. Больше базвордов по которым можно искать дополнительную информацию и тд.

Снова же если укажут, что концепция К неудачна в языке Я, то можно (чисто для себя) подумать почему.

— дженерики — делались изначально как шаблоны с++, все отличия и тормоза происходят от недостаточной мощности jvm

en.wikipedia.org/...enerics_in_Java

— дефендеры, концептуально добавлять методы в интерфейсы бред, хотя можно считать неким аналогом множественного наследования . попытка обойти ограничения jvm

— лямбды — их нет, есть финты ушами, которыми можно сэмулировать лямбды
даже сан говорит нам что
Java 8 is expected in September 2013 and will include at a minimum the features that were planned for Java 7 but later deferred.
Language-level support for lambda expressions (officially, lambda expressions; unofficially, closures) under Project Lambda.

en.wikipedia.org/...ava_8#Java_SE_8

— аннотации — некий микст препроцессора и pragmas. немного похоже на Template Haskell . попытка обойти ограничения jvm

— дженерики — делались изначально как шаблоны с++, все отличия и тормоза происходят от недостаточной мощности jvm

en.wikipedia.org/...enerics_in_Java

А можно указание цитаты из ссылки подтверждающие ваши высказывания.

— лямбды — их нет,

Да, пока что их нет в продакшене. А аналоги того что в девелоперских версиях?

— аннотации — некий микст препроцессора и pragmas.

А препроцессор — это точно компайл-тайм, прагма, вроде, так же.

концептуально добавлять методы в интерфейсы бред, хотя можно считать неким аналогом множественного наследования

Утверждение довольно спорное.

Суть в том что я не предлагаю обсуждать хорошо/плохо. Вопрос в том новшество и/или плагиат.

А можно указание цитаты из ссылки подтверждающие ваши высказывания.
The generic type information is then removed via a process called type erasure, to maintain compatibility with old JVM implmentations, making it unavailable at runtime. For example, a List<string> is converted to the raw type List. The compiler inserts type casts to convert the elements to the String type when they are retrieved from the list, reducing performance compared to other implementations such as C++ templates.
Because there is only one copy per generic class at runtime, static variables are shared among all the instances of the class, regardless of their type parameter. As a result, the type parameter cannot be used in the declaration of static variables or in static methods.
Да, пока что их нет в продакшене. А аналоги того что в девелоперских версиях?
появятся — обсудим. но врядли там можно придумать больше, чем уже придумано
А препроцессор — это точно компайл-тайм, прагма, вроде, так же.
ну на тему доступности в ран-тайм, ок. в принципе ничего сложного иметь подобие в с/с++, но там это не часть стандартного синтаксиса, поэтому под каждую задачу создается свое решение.... вплоть до плагинов к gcc
Суть в том что я не предлагаю обсуждать хорошо/плохо. Вопрос в том новшество и/или плагиат.
множественное наследование — плагиат.
По этой ссылке en.wikipedia.org/...enerics_in_Java

нет приведенной вами цитаты

The generic type information is then removed via a process called type erasure, to maintain compatibility with old JVM implmentations, making it unavailable at runtime. For example, a List<string> is converted to the raw type List. The compiler inserts type casts to convert the elements to the String type when they are retrieved from the list, reducing performance compared to other implementations such as C++ templates.

Because there is only one copy per generic class at runtime, static variables are shared among all the instances of the class, regardless of their type parameter. As a result, the type parameter cannot be used in the declaration of static variables or in static methods.

По тексту цитаты:

Где сказано что дженерики копировали с ЦПП? В тесте цитаты есть сравнение реализаций джавы и ЦПП, ибо вышли они из одной концепции.

происходят от недостаточной мощности jvm

Переводите правильно:

to maintain compatibility with old JVM implmentations

Не недостатка мощности, а для совместимости с другими реализациями.

появятся — обсудим.

Я не пытаюсь доказать “крутость” джавы. Я предлагаю обсудить концепции. Помимо того в бетте они уже есть.

но врядли там можно придумать больше, чем уже придумано

Так вот где уже придумали “функциональные интерфейсы”?

множественное наследование — плагиат.

Строго говоря, дефендеры — это не множественное наследование, как и примеси.

Где сказано что дженерики копировали с ЦПП? В тесте цитаты есть сравнение реализаций джавы и ЦПП, ибо вышли они из одной концепции.

ну раз уж jvm написано на с++, то легко сложить одно с другим

Не недостатка мощности, а для совместимости с другими реализациями.

одно и тоже, сравните с «не захотели менять jvm и реализовали на уровне компилятора»

Я не пытаюсь доказать «крутость» джавы. Я предлагаю обсудить концепции. Помимо того в бетте они уже есть.

например я знаю несколько php/nodejs фреймворков активно использующих лямбды , как часть обычного процессинга. раз уж вы хотите обсудить концепции, давайте обсудим сравнивая практические вещи — то что есть в java фреймворках и то что есть в фреймворках на других языках

Строго говоря, дефендеры — это не множественное наследование, как и примеси.

как раз строго говоря они служат одной и той же цели — написать функциональность единожды, использовать в разных классах

одно и тоже, сравните с «не захотели менять jvm и реализовали на уровне компилятора»

Как вы легко понятиями манипулируете. А цпп программы нужно под каждую платформу каждый раз перекомпилировать ;-)

как раз строго говоря они служат одной и той же цели — написать функциональность единожды, использовать в разных классах

Любой яп служит одной цели — писать программы. Следственно все яп плагиат с машинных кодов.

Как вы легко понятиями манипулируете. А цпп программы нужно под каждую платформу каждый раз перекомпилировать ;-)

я вообще про то, что майкрософт в дотнете не поленился и внес поддержку дженериков на уровне VM

Любой яп служит одной цели — писать программы. Следственно все яп плагиат с машинных кодов.

можно и так сказать

я вообще про то, что майкрософт в дотнете не поленился и внес поддержку дженериков на уровне VM

Опять вы манипулируете словами. Разницу между «поленился», и «обратная совместимость» понимате или нет?

т.е. байткод сгенеренный последним компилятором все также обратно совместим с первыми jvm ?

Байкод сгенеренный предедущими компиляторами совместим с последними джвм.

ну в дотнете как-то же решили.

В скале вон тоже уже почти както решили. И что?

.net 1.1 обратно совместим с .net 4.5.

давайте обсудим сравнивая практические вещи — то что есть в java фреймворках и то что есть в фреймворках на других языках

Тема про язык, а не про фреймворки. Если вам интересна тема про фреймворки, создавайте, с радостью выскажу свое «неимоверно важное мнение» :)

как раз строго говоря они служат одной и той же цели — написать функциональность единожды, использовать в разных классах

В дефендерах не наследуется состояние, а только базовое поведение (алгоритмы по умолчанию) в отличии от примесей или полноценного множественного наследования.

В дефендерах не наследуется состояние, а только базовое поведение

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

потому что мне дефендеры пока что кажутся теми же примесями с запретом на свойства.

Скорее на поля. То есть вы можете определить геттер/сеттер и вызывать их в дефолтной реализации. Но что они делают отдается на откуп уже тому кто реализует интерфейс.
Примесь же, по факту, дает возможность сделать сомодостаточный класс и по факту их просто склеивать при надобности.
Дефендер — все-таки требует чтобы вся работа с состоянием была в реализации. То есть на дефендерах вы можете сделать только стейтлесс класс. Второй момент что дефендеры предполагаются именно как заглушки, предполагается что все что надо человек таки будет переопределять в реализации.

Вот простой пример Iterator:

public interface Iterator<e> {
boolean hasNext();

E next();

/**
* Его реально использовали 1 случай из 1000 :)
*/
public default void remove() {
throw new UnsupportedOperationException("remove");
}

/**
* А этого метода не было и для него добавлена дефолтная реализация, но если окажется что в вашей реализации можно итерироваться оптимальнее, можете переписать.
*/
default void forEach(Block block) {
Objects.requireNonNull(block);
while (hasNext())
block.accept(next());
}
}

Их вроде как делали, с целью возможность расширять АПИ после их публикации, а не чтобы реализовать множественное наследование.

public default void remove() { throw new UnsupportedOperationException("remove"); }

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

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

просто представьте при каких обстоятельствах кто-то поймает этот експешн, и что он скажет об авторе интерфейса

А ну-ка назовите сколько раз за последний месяц вы пользовались ремувом итератора? Потом за последний год?

А ну-ка назовите сколько раз за последний месяц вы пользовались ремувом итератора? Потом за последний год?

обычно быдлокодеры так и говорят — «в большинстве случаев оно же работает»

Ну для обычных коллекций то все определено.

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

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

не , я догадывался что в java все плохо, но что бы так ....

Это значительно лутше, чем манки-патчинг, столь вами любимый

Лол причем тут мощность jvm? Слово мощность в данном контексте не имеет никакого смысла. Проблема дженериков явы в том, что они внутри делают boxing unboxing, что само по себе затратная задача. Например дженерики шарпа резолвят это во время компиляции, потому дженерики шарпа работают быстрее, чем явовские.

мощность в том смысле, что jvm не поддерживала дженерики, но вместо расширения jvm — реализовали через кодогенерацию

но вместо расширения jvm — реализовали через кодогенерацию

че?

Лол причем тут мощность jvm? Слово мощность в данном контексте не имеет никакого смысла.
Как нима смысла? А наехать, это по вашему не смысл?
Проблема дженериков явы в том, что они внутри делают boxing unboxing
(Ан)Боксинг — это только если вы работаете с примитивами (для шарпа это имеет значение так как там есть структуры, в джаве же их нет). При использовании объектов, дополнительных затрат 0.
Например дженерики шарпа резолвят это во время компиляции, потому дженерики шарпа работают быстрее, чем явовские.
Почитайте таки про шарповые/джавовские дженерики — они служат для разных целей.

А вот про разные цели попродробнее, я на Java не кодил особо, с C# сейчас на Scala перехожу. Я всегда думал, что Generic в обоих языках используется для подстановки типов. Типа List<int> везде внутри T заменит на int, тоесть шаблон. Разве не так?

Разве не так?

Краткая версия: нет.

так что же делает generic в java, я нагуглил информация, разницы между C# и Java не нашел, кроме реализации.

Я — тупой, разница существенная. Но отсылаясь к изначально предпосылке, все же имхо Generics в Java и C# концептуально одно и тоже(шаблонами в С++ не разбирался).

При использовании объектов, дополнительных затрат 0.

судя по вики, каждый get вызывает type casting что приводит к издержкам

каждый get вызывает type casting что приводит к издержкам

Fixed:

При использовании объектов, дополнительных затрат ~0.

интерфейсы? вроде в ней первый раз появились. IoC?

интерфейсы? вроде в ней первый раз появились.

Протоколы из Objective-C очень похожи (а знать вполне возможно что-то похожее могло быть в Smalltalk, хотя поверхностно я там ниче такого не увидел), или есть существенные отличия.

интерфейсы

— syntax sugar вокруг полностью виртуальных классов в С++.

IoC — это не фича языка, ИМХО.

Підписатись на коментарі