Pull to refresh

Comments 55

The Oberon language — together with the Oberon System — was designed and implemented
by Prof. Niklaus Wirth and Prof. Jrg Gutknecht at ETH Zrich from 1985 to 1987. Since
then it has been used intensively for teaching but also for projects at ETH and elsewhere.

Нет, действительно скотина: ворвался в дом, наследил, испортил [распрямляя кочергу] хо… ро… шую вещь!.. (с) Ш. Холмс
К счастью, лямбды можно использовать на Андроиде через Retrolambda бэкпорт лямбд, method references и  try-with-resources, работает хорошо, конфликтов синтаксиса в иде нет.
А стримы можно использовать через Lightweight-Stream-API, но я его ещё не опробовал, поэтому не знаю, насколько хорош бэкпорт.

github.com/orfjackal/retrolambda
github.com/aNNiMON/Lightweight-Stream-API
Java сообщество вообще замечательное в этом плане.
Нет ну это все равно минутка юмора — «Java: 20 лет инноваций». Java, Карл! 20 лет инноваций!
На самом деле, нет. Если рассматривать не только синтаксис языка Java (которые довольно консервативен), а вообще все open source библиотеки, фреймворки и программные решения в мире Java, то окажется что инноваций там очень много, одно перечисление инноваций открытых программных решений на основе одного только Hadoop'a займет несколько страниц.
Ну тема-то все-таки про сам язык, а не библиотеки, и я не хейтер языка, а говорю правду. Если бы я программировал на JS в качестве основного языка, я бы не стал писать о том, что в нем все понятно в плане конвертации типов и т.д. (вспоминаем известную табличку истинности сравнений и наследование на прототипах), если бы на C++, то признавал бы катастрофически быстрое изменение языка, за которым сложно успеть (в последнее время), а вот в случае java'ы — медлительность развития. Ну кто может не кривя душой сказать, что ожидание Java 7 ему показалось незаметным? Вот Вики на эту тему. Любите язык — пожалуйста, но умейте признавать недостатки (без молчаливых минусов в карму =\ ).
1) Кто сказал что тема только про язык, а не про всю платформу Java?

2) Библиотеки гугла и апатча или фреймворки вроде spring, hibernet, guava это давно уже де-факто опциональная часть языка от сторонних разработчиков, так как не требует ничего кроме пары строчек в pom'е и используются практически всеми,

3) Медленность развития это не только минус, но и плюс, так как в крупном enterprise важнее стабильность, чем синтактический сахар и фичи, благо его полно в сторонних библиотеках

4) Мне ожидание Java 7 показалось незаметных, так как во всем местах где я работал (а это крупные международные фирму) никак не слезут с Java 6, ибо legacy и enterprise,

5) ну и в конце концов, я не могу ставить минусы в карму (и если бы мог то все равно бы не ставил)
Посмотрел в профиль, как и ожидалось метки C#, .Net и не слова про Java. У программистов C# есть ряд устойчивых мифов про Java:

Дело в том что в развитии C# выбрали модель «добавить как можно больше фич и сахара как можно быстрее», в развитии Java придерживаются модели «каждая фича сначала обкатываются на open source библиотеках и только абсолютно нужное и проверенное попадает в сам язык». Для тех кто хочет много сахара в самом языке есть scala и kotlin совместимый с остальным кодом Java, тем кому нужны фичи есть немеренное кол-во open sourc'a (в том числе от крупнейших фирм, вроде гугла) на любую задачу. Поэтому программистам C# кажется что Java устарела, не понимая что синтаксис языка Java это даже не верхушка айсберга, а одна десятая (если не сотая) от реального мира Java (причем бесплатного, открытого и доступного простым добавлением пары строчек в конфиг сборки).
«Конфуцианцы и буддисты спорят друг с другом потому, что конфуцианцы не читают буддийских книг, а буддисты не читают конфуцианских книг. И те, и другие судят о том, чего они не знают.»
Чень Цзижу

Джон Скит в своей книги провел пару сравнений, условно.
Да, я не спорю про C# (хотя достаточно долго его изучал), я говорю только о том что знаю (Java). Если сказал что-то не так поправьте. Вообще я даже пытаться не буду спорить что Java лучше C#, это исключительно вкус фломастеров и бессмысленый холивар, но лично мне больше нравиться философия Java, чем C#.
Ух, ветка куда-то не туда ушла. Изначально же спор возник на почве «Java — это только язык» vs «Java — это платформа» )
немножко добавлю холивара про фичи языка — полгода назад стал активно писать проекты под Android на java (фактически перешел на нее с C#) и есть пару веще с которыми мне сейчас тяжело мириться:
1) цирк с примитивными типами long--Long с невозможностью юзать первые в генериках (уж молчу о том, что нельзя писать свои кастомные Value Types)
2) отсутсвие var (или как в плюсах — auto). хоть за сниппет .var спасибо IDE. но все равно не то. сравните:
FooFactoryFactory foo = new FooFactoryFactory();
vs:
var foo = new FooFactoryFactory();

3) лямбды и Stream — очень рад что это появилось в яве, хоть до C# LINQ не дотягивает отсутсвием возможности разбора дерева выражения. Ну и через костыли в принципе подключаемо к андроиду.
4) ну и конечно же async/await
представьте что вам нужно послать ассинхронный реквест и по приходу ответа обновить текст на UI:

android java:
client.sendRequest(request, new ResponseCallback() {
	@Override
	public void onResult(Object object) {
		currentActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				currentActivity.title.setText("done!");
			}
		});
	}
});

android C#:
var responseObj = await SendRequest(request);
//runOnUiThread не нужен т.к. await вернет первоначальный контекст
currentActivity.title.Text = "done"

Но это сравнивая решения в лоб без библиотек типа robospice, javaRX (за которую большое спасибо)
Интересное сравнение!
1) Да есть этот минус. Под него даже костыли делали в Java 8 в Stream API — были свои stream для примитивов.
2) Насколько я понимаю идеологию Java, это никогда не введут — в Java в почёте строгая типизация. А в var не будет работать, насколько я понимаю.
3) По этому пункту ничего сказать не могу — сам Stream API не много пользовался. Скорее всего это сможет прокомментировать lany
4) Как вы сами сказали, сравнивали без javaRX — с лямбдами это было бы менее многословно.

Добавлю тут erase generic — если нужно знать тип переменной, то приходится помимо неё так же и её класс передавать, что немного увеличивает код. Хотя type safe остаётся :)

А вообще, вы пробовали Kotlin? e.g. habrahabr.ru/post/258683 Насколько я понимаю, это то что вам нужно.
2) — var в C# не ослабляет типизацию. это автовычисление типа по выражению справа.
4) да, сам подумал так, но тогда могу усложнить пример — надо выполнить 3 разных запроса один за одним обновляя текст на UI:
await client.SendRequest1(request1);
currentActivity.title.Text = "1/3";
await client.SendRequest2(request2);
currentActivity.title.Text = "2/3";
await client.SendRequest1(request3);
currentActivity.title.Text = "3/3";

vs:
client.sendRequest1(request1, o -> currentActivity.runOnUiThread(() -> {
	currentActivity.title.setText("1/3");
	client.sendRequest2(request2, o -> currentActivity.runOnUiThread(() -> {
		currentActivity.title.setText("2/3");
		client.sendRequest3(request3, o -> currentActivity.runOnUiThread(() -> {
			currentActivity.title.setText("3/3");
			}));
		}))
	}));

писал в блокноте поэтому уверен что в java напутал в конце со скобками ибо нечитаемо.

зы: пробовал. на котлин вся надежда.
2. Собственно ниже ответили на счёт var — List list = new ArrayList не аналогично var list = new ArrayList, а если учесть что интерфейс предпочтительно перед реализацией, то это в общем спорная фича.
Для этого кейса да. но в большинстве других где тип слева такой же как справа var необходим. особенно если название типа очень большое, к примеру:
GroupConversation.GroupConversationParticipant participant = new GroupConversation.GroupConversationParticipant();

если мы не приводим к базовому/интерфейсу — эта копипаста не нужна и должна быть заменена на
var participant = new GroupConversation.GroupConversationParticipant();
Ну если проблема только в длинном наименовании типа переменной, то это вообще не проблема — IDE сделают всю работу за программиста по написанию типа.
я про читабельность — лишняя информация для глаз. и так понятно какого типа переменная.
Пример искусственный. Импортируйте вложенный класс GroupConversationParticipant, получите

GroupConversationParticipant participant = new GroupConversationParticipant();

В современном коде переменные вообще не нужны, каждый метод должен состоять из одного предложения return :D
Для локальной переменной нет никакого смысла ограничивать её тип интерфейсом — она не более чем деталь реализации метода. Интерфейсы имеет смысл использовать на границе API, но как раз там var в C# недоступен.
Почему же нет смысла? Без этого будут лишние головняки при рефакторинге, если метод длиннее трёх строчек. В какой-нибудь ветке вы в будущем захотите присвоить туда Collections.singletonList, и всё равно придётся менять тип.
А в чем проблема поменять тип, если это вдруг понадобится? Ну будет дифф не на две строки, а на три.

(Как показывает практика, в 99% случаев — не понадобится, и по умолчанию имхо стоит исходить из этого.)
Точно так же никакой проблемы нет в том, чтобы сразу использовать интерфейс. Это нулевые затраты.

Всё становится сложнее, когда программист автоматом добавляет return из метода, IDE выводит возвращаемый тип из типа переменной, программист не парится (приватный метод же, деталь реализации) и присваивает снаружи тоже в ArrayList. Потом всё это прорастает через цепочку методов (хорошо, если все приватные) и кучу переменных (а то и каких-нибудь Map<String, ArrayList<String>>), и одно исправление во внутреннем методе требует замены кучи типов. Гораздо проще всегда по умолчанию использовать интерфейсы и не думать об этом. Конкретный тип может потребоваться, только в очень специфических случаях (например, анализ дампа памяти показал, что ArrayList.trimToSize вызвать нелишне).
>> Точно так же никакой проблемы нет в том, чтобы сразу использовать интерфейс. Это нулевые затраты.

В плане написания — возможно. В плане чтения, особенно когда активно используются дженерики, и там еще что-то вложенное — var проще.

>> Всё становится сложнее, когда программист автоматом добавляет return из метода, IDE выводит возвращаемый тип из типа переменной

А вот тут я уже замечу, что нехорошим в данном случае является именно автовывод типа возврата. Границы метода — они неспроста.
4. В таком ключе await явно выигрывает, да. Вообще идея интересная — внести в синтаксис поддержку многопоточности. Может в дальнейшем это сделают — всё таки направление в развитии в сторону многопоточности явно прослеживается, так может и в синтаксис внесут.
*я всегда буду обновлять комментарии*, хотя ответ получился немного о другом, так что все ок

Позволю себе ответить за автора оригинального комментария.

1. Что значит «были»? Они все еще есть.

2. var к строгой типизации не имеет ни малейшего отношения. После type inference (а в восьмерке он довольно хороший) будет точный тип. Т.е. это фича исключительно компилятора. Тут есть другой момент: я не могу заменить на var объявление
List<String> list = new ArrayList<String>;

т.к. переменная станет типа ArrayList, что не очень хорошо.

3. А тут и нечего говорить. Действительно нельзя. Лябда — это просто специфический синтаксис для создания реализации интерфейса. Если уж очень нужно, то можно вытащить байткод метода, в который скомпилировалось тело лямбды (что само по себе не совсем тривиальная задача) и уже как-то анализировать его. Но это скорее грязные хаки, нежели «возможность разбора дерева выражения».

4. Тут не в лябмдах дело. rx — скорее другой подход к проектированию. Async/await же позволяет писать плоский код, вместо вложенных коллбеков. И это прекрасно.
2. объект в переменной как был ArrayList, так и останется. Что плохого в том что тип переменной это отражает? Если потом этот list возвращается как List или передается в функцию которая ждет интерфейс — ничего не изменится, наружу точно так же и будут торчать интерфейсы… Единственный случай, который в голову приходит, это если в эту же перменную надо будет позже положить другой объект, который не ArrayList, а List. Нууу, explicitly typed variables никто не отменял.
Спасибо, очень ценное замечание. И в случае локалов действительно пофиг. Проблема если так делать с филдами. В этом случае как раз наружу торчат классы.
А в C# филды var'ом объявить нельзя :)
А что я могу прокомментировать? Ну да, разбор синтаксического дерева в том виде, как это сделано в LINQ, отсутствует в Java. Мне вообще нравятся языки, где разработчики думают не только над тем, какую бы ещё фичу добавить, но и над тем, какие фичи не добавлять. Получается не разрозненное месиво функционала, а концептуально выдержанный язык.
Если вы понимаете что это такое, то наверняка знаете какой профит это дает. Была бы такая фича — была бы возможность в java написать такой код
persons.stream().filter(p -> p.getAge() > 18).limit(100).collect(Collectors.toList());

который бы при выполнении сконвертился бы в SQL
"select top(100) * from persons where age > 18"

и вернул объекты из бд. Но в целом согласен — фичи надо вводить с умом
Да, естественно, я это понимаю. На мой взгляд это слишком ненужная абстракция, которая легко протекает. Если я в фильтре вызову Java-метод или обращусь к другой структуре данных (скажем .filter(mySet::contains))? Всё равно придётся помнить, что можно делать и чего нельзя. Java очень консервативна в плане адаптации синтаксиса под конкретные частные задачи. Тут ни перегрузки операторов, ни даже поддержки регекспов на уровне /синтаксиса/. Зато читать код и анализировать сторонними тулзами гораздо легче, чем разбираться, SQL-запрос тут под капотом или нет.
Да, протекает. Но не так уж и легко — в EF (и даже в дотнетовской реализации Hibernate) всё нужное интерпретируемо в SQL даже если вы в фильтре вызовете contains на какой-нибудь локальный лист. Давно не сталкивался с ошибками того, что я что-то не то сделал в лямбдах в linq. Раньше в спорах java vs C# в ход шел козырь кроссплатформенность. Сейчас он как-то стал неактуален с xamarin. И пошёл новый козырь: у нас фичи продумываются столетиями и всё идеально, а у вас бардак :-).
Да причём тут споры и козыри? Пишите на чём нравится. Я не пытаюсь вас убедить, что Java лучше шарпа. Это прекрасно, что в мире много языков с разной философией. Зачем делать из Java ещё один C#, если C# уже есть? Зачем делать из Java Скалу или Котлин, если они уже есть? Java — это Java.
Ай ну это скучно же. Где холивар, переход на личности и рукоприкладство?
Не, главный козырь, в том что куча проверенного и оттестированого open sourc'a на любые цели, которым занимаются в том числе и крупнейшие компании, в платформе Java для программистов важнее любого синтактического сахара и фич других языков. Но вообще мерятся ху… языками занятие бессмысленное, пока есть конкуренция между языками они развиваются и это замечательно. :)
Я вот тоже так думал. Сам старый явист, но пришлось пописать гуйню на C#. Поначалу протащился потом стало грустно возращаться на Java под андроид c его java 6+++. Но retrolambada, javaRX, kotlin… ну че мне в этом c#? А тут еще и scala есть для сервесайда. И все это совместимо во все стороны. И чувствую жизнь то налаживается Ж)

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

1) Примитивные типы спрятаны. Есть даже ограниченная возможность писать свои value types (только на основе существующих примитивов).
2) val/var. val в C# мне не хватало.
3) Разбор дерева на этапе компиляции. См. slick. На самом деле механизм мощнее, чем в C# — вот пример от меня.
4) Есть.
>> в развитии C# выбрали модель «добавить как можно больше фич и сахара как можно быстрее»,

Это в равной степени миф. Я вам советую почитать записи в блоге Эрика Липперта про дизайн языковых фич, и design meeting notes из страницы Roslyn на GitHub. Там можно увидеть, насколько нещадно на самом деле режутся списки предлагаемых фич.
Есть вещи которые трудно исправить сторонними библиотеками. Например половинчатая система дженериков.
C# очень быстро развивался, так как просто позволял себе ломать обратную совместимость и быстро выкинул из себя не очень удобные решения. А вот java тянет с собой старый код, а вместе и кучу проблем.
К сожалению это так, с другой стороны иначе legacy код никогда не получилось бы перевести на новые версии Java. Это даже сейчас не так просто перейти с 6 на 7 или 8, а если бы сломали обратную совместимость… Для тех кто хочет Java без обратной совместимости есть Scala и Kotlin.
В scala ровно те же проблемы с дженериками, что и java. И scala используется гораздо реже.
Учитывая как бизнес быстро переходит хотя бы с 6 на 7, то ломание совместимости не очень бы сильно и замедлило динамику. Так как старые проекты очень редко переводят на новую платформу и основной приток идет за счет новых проектов.
we need to go deeper — в Java 7 были большие изменения в JVM: быстрый гуглёж habrahabr.ru/post/125202 плюс добавление NIO2. А так язык, да, не сильно изменился — try-with-resource, multi-catching и swich-case-string. Вообще JVM с каждой версией сильно меняется, без изменения самого языка. Пруфы — выступления на JPoint разработчиков JVM.
P.S. Спорить не сильно хочется, но, надёюсь, мой комментарий сделай вас лучше, как программиста, и вы будете различать синтаксис и платформу. Собственно, вам уже выше объяснили, но дополню их комментарии.
«Самого главного глазами не увидишь». Собственно самая главная фича платформы Java 7 — это invokedynamic. Хотя в самом языке Java она в семёрке ещё не использовалась, но дала толчок для дальнейшего развития. JRuby переписали на invokedynamic, он стал в разы быстрее. Стал возможен проект nashorn. Ну и быстрые и лёгкие лямбды в восьмёрке.
Точно! Я просто забыл, когда он появился — думал, что в 6-ке и не стал писать. Позор на мои седины :)
По-моему, уже стоит разделять java, jvm и около-jvm-языки-и-библиотеки.
В сабже речь идёт о Java как платформе/экосистеме.
Не стоит. В этом сила java как платформы. Есть jvm — как машина. Есть Java — яызык как некое универсальное среднее. Есть либы и jvm based языки которые вносят огромную гибкость в Java как платфрму
? "...Java появилась в чрезвычайно важный момент для истории программирования. До тех пор в разработке ПО царствовали три языка: Fortran в научных вычислениях, COBOL в бизнесе и C (С++ тогда только начинал распространяться) во всех остальных проявлениях коммерческого программирования..."? Правда?! Фортраныч остался на PDP-11 и ЕС-серии, и в 90х они были только в музеях и «очень инновационных» вузах. Да, машинки были но, на фортране мы писали лишь для академии наук, на производстве — паскаль, мампс. С появлением персоналок — Turbo Pascal, DBase(Paradox, Clipper, FoxPro), Turbo C/ MS C. To что кто-то писал на фортране и позже- это возможно(интельский, вэтком...), но по масштабам запрса… На COBOLе писали, по ходу, только в штатах, у них оплата была за количество строк кода и по этому тексты(простыни) были очень кстати.

А момент стал «чрезвычайно важным» — титаническими усилиями MS подмять программиское сообщество под себя, и посадись энтерпрайсь на офис важнейшей компании.
Отличная платформа… Долгих лет и всестороннего развития!
> В последние годы Java стала использоваться и на мобильных платформах, благодаря Android.

В последние? А J2ME?
Скорее «Java вернулась на мобильные платформы».
Java появилась в чрезвычайно важный момент для истории программирования. До тех пор в разработке ПО царствовали три языка: Fortran в научных вычислениях, COBOL в бизнесе и C (С++ тогда только начинал распространяться) во всех остальных проявлениях коммерческого программирования.
Что за чушь? Какой нафиг COBOL и Fortran в 1995 году? В то время по планете яростно шагал Delphi, был на подходе C++ Builder. Корпоративный рынок уже принадлежал Microsoft а с ним и MS Visual C++ c MFC впридачу.
… и SQL(IBM, Oracle & MS), автор слишком был молод…
И FoxPro, в те времена тоже был трендом.
Sign up to leave a comment.

Articles