avva: (Default)
[personal profile] avva
(эта запись может быть интересна разве что программистам)

Прочитал Java Generics FAQ. 500 страниц, между прочим, в PDF-версии. 500 страниц. Когда вы в последний раз читали FAQ на 500 страниц? Ну вот и я тогда же. С трудом верится даже теперь, по прочтении. Правда, там много места занимают бесконечные индексы и оглавления и заголовки, так что реально "мяса" страниц на 350. Но и этого довольно.

Теперь я понимаю, зачем в Джаве класс Enum определяется, как Enum<E extends Enum<E>>, что это в точности значит, и зачем это нужно. Не уверен, что мне нравится, что я это теперь понимаю.

Многие объяснения в этом фэке читаются, как один сплошной WTF. Ты понимаешь, в процессе чтения, почему это сделано так, а не иначе. Почему и тут исключение, и тут, и это надо делать через задницу, а то даже через задницу не сделать. Почему - один пример наугад из сотни - все обычные вещи с параметризованными типами можно делать, а вот создавать массивы из них нельзя. Кроме случая, когда они параметризованы неограниченными вопросиками. Ты понимаешь, почему это так получается, но не оставляет ощущение глубокого WTF на тему того, как мучительно и болезненно эти дженерики врастают в плоть языка. Сказать, что это leaky abstraction - ничего не сказать; эта лодка не протекает, она буквально состоит из воды.

Вот один из прекрасных вопросов из этого FAQ:
What is the difference between a Collection<Pair<String,Object>>, a Collection<Pair<String,?>> and a Collection<? extends Pair<String,?>>?
Ответ начинается так: "All three types refer to collections that hold pairs where the first part is a String and the second part is of an arbitrary type. The differences are subtle." Потом на двух страницах объясняются эти subtle differences.

По-моему, внесение дженериков в Джаву было огромной ошибкой. Главная польза от них - строгая типизация коллекций - не оправдывает той огромной цены, которую пришлось заплатить: сложностью языка, читабельностью и понимабельностью кода. Учитывая то, что динамическая безопасность у коллекций и так была, необходимость безопасности на уровне компиляции была кем-то, по-видимому, сильно преувеличена. Да, конечно, намного удобнее и проще написать ArrayList<String>, и знать, что попытка всунуть туда что-то другое вообще не скомпилируется. Это удобнее, чем всунуть что-то не то в ArrayList и получить исключение в рантайме, когда это взяли и попытались привести к String. Баги ловятся быстрее. Но насколько быстрее, как часто на практике это оказывалось существенным, и оправдывает ли эта польза введение архитектуры, приводящей к Enum<E extends Enum<E>> или вопросам, подобным процитированному выше?

Одним из главных преимуществ Джавы по сравнению с C++ было именно grokability исходного кода средним программистом: посмотрев на исходник какого-то класса, который он раньше не видел, средний программист на Джаве - не гуру, не хватающий звезды с неба итд. - мог сказать, что делает каждая строка и зачем это нужно. Дженерики это свойство языка с помпой похоронили. Кто были люди, которые приняли решение так поступить, и радовались ли они красивому трюку само-референтных типов? И это только ущерб понятности кода, не говоря о всем этом огромном числе исключений и плохой совместимости с существующими частями языка - массивами, рефлекцией, исключениями, итд. итд. итд.

Можно ли было добиться той же пользы, что дали дженерики, менее разрушительными способами? Пусть не той же, но главной ее части, мне кажется, можно было. Скажем, какая-нибудь аннотация в момент создания коллекции, подсказывающая компилятору, что там должно быть. Просто сказать: в эту коллекцию я хочу класть строки, или такие-то пары, итп. И пусть компилятор проверяет, что сможет, и вставляет эксплицитное приведение к строкам или парам, когда мы из коллекции что-то достаем. И все. Без extends, без wildcards, для всех мест, где это действительно надо, пусть программист продолжает приводить эксплицитно. Конечно, такая аннотация не покрыла бы все случаи, но самые простые и важные, думаю, покрыла бы. Главное ведь то, что у дженериков почти нулевой эффект на рантайм, поэтому необязательно было вносить их глубоко в ткань языка, so to speak; подсказки компилятору достигают схожей цели. Простая (простая!) и удобная подсказка захватила бы, мне кажется, большинство багов с типами в коллекцях, которые до дженериков проявлялись только в рантайме.

(disclaimer: я редко и мало пишу на Джаве, и не эксперт в ней)
Page 1 of 2 << [1] [2] >>

Date: 2010-05-21 09:39 pm (UTC)
From: [identity profile] solomon2.livejournal.com
А inner classes вас не раздражают?

Date: 2010-05-21 11:03 pm (UTC)
From: [identity profile] avva.livejournal.com
Да нет в общем.

(no subject)

From: [identity profile] rainman-rocks.livejournal.com - Date: 2010-05-29 12:27 pm (UTC) - Expand

Date: 2010-05-21 09:43 pm (UTC)
From: [identity profile] psr1913plus16.livejournal.com
Я сам начал пользоваться Java с той версии, в которой появились параметризованные типы. До этого старался с ней не сталкиваться; по возможности сваливать на подчиненных и т.д.

Наверное, мой узус гораздо уже того, что вы описываете. Дальше List<POJO> я не иду. Просто незачем. Хотя бы потому, что мои задачи всегда опираются на схему (базы) данных, а JPA оперирует именно этими POJO и List'ами из них.

Date: 2010-05-21 10:22 pm (UTC)
From: [identity profile] avva.livejournal.com
Конечно, всегда можно ограничить себя самыми простыми случаями. Но увы, читать и работать приходится не только над своим кодом.

Date: 2010-05-21 09:44 pm (UTC)
From: [identity profile] trurle.livejournal.com
В C++ проблем не меньше, и, что характерно, коллекции получились просто загляденье, но за это заплачено механизмом которые нередко приводит к сводящему с ума когду. У меня есть нехорошее чувство что разработчики параметризованных типов в обоих случаях думали "ах, какие замечательные библиотеки коллекций можно будет построить с применением наших генерализованных типов!"

Date: 2010-05-21 10:10 pm (UTC)
From: [identity profile] pin-dragon.livejournal.com
В С++ много чего может привести к сводящему с ума коду.
Но там, хотя бы, все кунштюки с темплейтами можно оправдать тем, что с их помощью можно делать (всё же, полноценный механизм кодогенерации), в джаве же такого нет =(

(no subject)

From: (Anonymous) - Date: 2010-05-21 10:47 pm (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-21 10:57 pm (UTC) - Expand

(no subject)

From: [identity profile] arcbishop.livejournal.com - Date: 2010-05-22 01:08 am (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-05-22 01:26 am (UTC) - Expand

(no subject)

From: [identity profile] arcbishop.livejournal.com - Date: 2010-05-22 01:30 am (UTC) - Expand

(no subject)

From: [identity profile] tolko-ne.livejournal.com - Date: 2010-05-22 06:04 am (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-22 01:57 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 10:08 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 11:43 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 01:01 pm (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-22 01:50 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 02:11 pm (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-22 02:25 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 02:36 pm (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-22 02:44 pm (UTC) - Expand

(no subject)

From: [identity profile] alexey-rom.livejournal.com - Date: 2010-05-22 09:05 pm (UTC) - Expand

(no subject)

From: [identity profile] madfire.livejournal.com - Date: 2010-05-23 06:17 pm (UTC) - Expand

(no subject)

From: [identity profile] skipy-ru.livejournal.com - Date: 2010-05-25 08:26 am (UTC) - Expand

(no subject)

From: [identity profile] pin-dragon.livejournal.com - Date: 2010-05-26 07:26 pm (UTC) - Expand

(no subject)

From: [identity profile] tolko-ne.livejournal.com - Date: 2010-05-21 11:10 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-21 11:47 pm (UTC) - Expand

(no subject)

From: [identity profile] tolko-ne.livejournal.com - Date: 2010-05-22 12:03 am (UTC) - Expand

(no subject)

From: [identity profile] zelych.livejournal.com - Date: 2010-05-22 11:31 am (UTC) - Expand

(no subject)

From: [identity profile] nm-work.livejournal.com - Date: 2010-05-22 05:49 pm (UTC) - Expand

(no subject)

From: [identity profile] nec-p1us-u1tra.livejournal.com - Date: 2010-05-22 08:18 am (UTC) - Expand

Date: 2010-05-21 09:46 pm (UTC)
From: (Anonymous)
Просто сказать: в эту коллекцию я хочу класть строки, или такие-то пары, итп.

Именно это генерики и делают.

Collection<String>

Вот, я сейчас сказал, что в эту коллекцию я хочу класть строки. Компилятор проверяет, что может, и вставляет эксплицитное приведение к строкам или парам, когда мы из коллекции что-то достаем. Хотите, чтобы это делалось проще? Предложите свой дизайн. Не бойтесь, завтра же начните разрабатывать, целый выходной впереди. (Hint: это займет пять лет, и получится хуже, чем существующий дизайн. Been there, done that.)

Date: 2010-05-21 10:17 pm (UTC)
From: [identity profile] avva.livejournal.com
Они не делают именно это. Они встраиваются в систему типов языка; подсказка, которую я предлагаю, этого бы не делала.

С одной стороны, дженерики говорят программисту: Collection<String> и Collection<Number> - два совершенно разных типа. С другой стороны, у рантайма есть свое представление о типе, в которое это различие не укладывается. Это рантаймовое представление в свою очередь тесно связано с фундаментальными возможностями языка. В такой ситуации расщеплять систему типов на две - для компилятора и для рантайма - не может не привести к сложной, запутанной системе, которую будет тяжело понять.

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

(no subject)

From: (Anonymous) - Date: 2010-05-21 10:42 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-21 11:02 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 12:00 am (UTC) - Expand

(no subject)

From: [identity profile] another-felix.livejournal.com - Date: 2010-05-22 01:13 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 01:28 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 01:50 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 02:52 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 03:55 pm (UTC) - Expand

(no subject)

From: [identity profile] al-zatv.livejournal.com - Date: 2010-05-22 11:04 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 02:30 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-21 11:57 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 02:28 pm (UTC) - Expand

(no subject)

From: [identity profile] nm-work.livejournal.com - Date: 2010-05-22 05:44 pm (UTC) - Expand

(no subject)

From: [personal profile] allter - Date: 2010-05-25 06:39 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-25 06:40 am (UTC) - Expand

(no subject)

From: [personal profile] allter - Date: 2010-05-25 07:07 pm (UTC) - Expand

Date: 2010-05-21 09:59 pm (UTC)
From: [identity profile] dynamo.livejournal.com
Я как только подумаю, что мне надо прочитать 1400 страниц Bluetooth Core в том самом PDF-e, так сразу вешаться хочется..

Date: 2010-05-21 10:07 pm (UTC)
From: (Anonymous)
Еще по поводу Enum<E extends Enum<E>> хочется высказаться. Этой идиоме вообще-то сто лет в обед (я о ней знал, когда Джава еще о дженериках и не помышляла). Она решает наболевший примерно 15 лет назад вопрос о типизации бинарных методов в ООП (бинарные методы принимают два аргумента одинакового типа — сравнение, арифметика всяческая и т.д. и т.п.) Это вопрос принципиальный. Что если нам нужно работать с множеством типов чисел, матриц, векторов, многочленов и прочей дребедени? В рамках традиционного ООП приписать сигнатуру общей для всех, наследуемой операции "+" невозможно. Либо мы заводим 50 никак не связанных между собой операций "+", 50 штук "*", 50 штук gauss_elimination, 50 штук newton_raphson, бла-бла... либо мы с этим что-то делаем нетрадиционное.

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

Date: 2010-05-21 11:28 pm (UTC)
From: [identity profile] nec-p1us-u1tra.livejournal.com
И как это в Хаскелле справились, подумать только. Не иначе колдуны.

(no subject)

From: (Anonymous) - Date: 2010-05-22 12:17 am (UTC) - Expand

(no subject)

From: [identity profile] nec-p1us-u1tra.livejournal.com - Date: 2010-05-22 08:11 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 09:16 am (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 01:47 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 03:21 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 03:34 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 03:56 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 04:23 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 04:49 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 04:59 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 05:22 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 05:58 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 09:41 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 09:43 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 06:00 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 07:21 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 09:17 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 03:26 pm (UTC) - Expand

(no subject)

From: [identity profile] madfire.livejournal.com - Date: 2010-05-23 07:41 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 08:02 pm (UTC) - Expand

Date: 2010-05-21 10:42 pm (UTC)
From: [identity profile] kingoleg.livejournal.com
Поверь, генерики упрощают жизнь.

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

Особенно приясно старый 1.4 джава код "портировать" в 1.5, добавляя генерии к коллекциям. То тут то там выясняется, что в переменной хранится 2,3 а то и больше типов данных. И ты не понимаешь, в каком случае - какой. Ну что, добавляем переменную со строгой типизацией - и жить становится лучше.

Date: 2010-05-22 06:12 pm (UTC)
From: [identity profile] hervejoncour.livejournal.com
О! Стопудово, а ещё время от времени какой-нибудь "генний" из Бангалора засовывает в collection Object и потом кастирует его исходя из своих нужд ....

Вообще, конечно, приятно что они много чего добавили в 5-ой версии и потом расширили в 6-ой.

Date: 2010-05-21 10:55 pm (UTC)
From: [identity profile] anton-solovyev.livejournal.com
В прикладном коде дженерики чудесно работают, улучшают читабельность кода и вообще сильно облегчают жизнь. Практически.

Спасибо большое, тем, кто потратил время добавить их к Джаве. Чего бы это им не стоило.

Date: 2010-05-21 11:14 pm (UTC)
From: [identity profile] igorlord.livejournal.com
Oh, come on!

The type system is very logical (including your Collection
[Error: Irreparable invalid markup ('<pair<string,object>') in entry. Owner must fix manually. Raw contents below.]

Oh, come on!

The type system is very logical (including your Collection<Pair<String,Object>> - like example).

Basically, there is a simle rule: generic types name exact types, and if you want to allow for derived types, you need to use "extends" syntax. Also, everything is strongly types at the "parsing unit" level (a statement when parsing a statement; a function declaration and function contents when parsing a function; class declaration and class contents when parsing a class).


Now, I DO consider it a mistake to require the "extends" syntax. It would be best if a derived type could ALWAYS be used when a base type is mentioned. Java's stength has always been at ignoring little "features" in favor of simplicity.

Java, including its generics, is a so much cleaner language than C++, for example, where templates are just humongously complicated preprocessor macros, and defeat the "programming by contract" model.


As for "how do you make a Collection of Strings or Pairs?", the answer is that you should not do that, because "a String or a Pair" is a terrible abstraction, and, luckily, the language resists it! If "a String or a Pair" does represent some abstraction in your program, you should make a class that encapsulates this abstraction and then have a Collection of those classes.

Date: 2010-05-22 02:32 pm (UTC)
From: [identity profile] avva.livejournal.com
Basically, there is a simle rule: generic types name exact types, and if you want to allow for derived types, you need to use "extends" syntax.

I don't really understand what you mean by this. The "extends" syntax is needed to allow you access to the parameter type's methods inside your generic class. It's not useful for distinguishing base vs derived types; in fact, you can have an "extends X" that will only match the exact type X and not a descendant (when X is final).

As for "how do you make a Collection of Strings or Pairs?", the answer is that you should not do that,

I kinda agree with that, but I don't think I was making a point anywhere that generics are bad because they don't allow you to do this.

Date: 2010-05-22 12:04 am (UTC)
alexeybobkov: (Default)
From: [personal profile] alexeybobkov
Да, кстати о типах: дочитали ли вы книгу Пирса и что о ней думаете?

Date: 2010-05-22 07:45 am (UTC)
From: [identity profile] avva.livejournal.com
Нет, увы, отложил в сторону, когда был очень занят. Собираюсь вернуться к ней.

Date: 2010-05-22 01:08 am (UTC)
From: [identity profile] msh.livejournal.com
Мне кажется, что авторы Java никак не могут прекратить воевать с C++ и каждое нововведение рассматривают с точки зрения пользы для переманивания C++ программистов (у них там vector<int>? И мы сделаем Array<Integer>!) Поэтому решение с аннотацией хоть и было бы лучше, но в язык не попадет.

Причем, надо сказать, не помогает ведь. Я в основном пишу на C и C++, Java в руки мне попадает изредка - когда появились дженерики вроде стало так удобно ... а потом в коде полезли какие-то ужасы. Вот ведь доказательство поинта поста - смотрю на свой код написанный меньше года тому назад и не понимаю почему там именно Class<?>, а не просто Class. А ведь сам же и писал.

Date: 2010-05-22 01:47 am (UTC)
From: (Anonymous)
Raw types следует избегать, они нужны только для взаимодействия с legacy code.

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-05-22 02:08 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 02:33 pm (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-05-22 05:08 pm (UTC) - Expand

Date: 2010-05-22 01:17 am (UTC)
From: [identity profile] arcbishop.livejournal.com
Я поддерживал чужой код на java и одна из самых главных заноз была hashtable. В классе она объявленна, а что в ней хранится, без брейк-поинта в дебайгере выяснить не реально. Generics эту проблему решили, и слава богу.
А то что сдуру можно и хер сломать, так это давно известно.

Date: 2010-05-22 03:32 am (UTC)
From: [identity profile] s1m.livejournal.com
C# is be doing just fine with generics. I am not an expert in Java but generics in C# seem to be doing exactly what they need to be doing.

Date: 2010-05-22 09:18 pm (UTC)
From: [identity profile] alexey-rom.livejournal.com
The major difference is that .NET generics don't use type erasure (which really seems to be a very bad idea).

Date: 2010-05-22 04:04 am (UTC)
From: [identity profile] selfmade.livejournal.com
Может я чего-нибудь не понимаю, но почему бы не взять красивые и приятные в использовании дженерики из C#?
Дженерики появились в C# раньше, чем в Java, хотя первые версии C# были частично слизаны с Java. С тех пор C# шагнул сильно вперёд. Теперь очередь Java слизывать.

Date: 2010-05-22 07:46 am (UTC)
From: [identity profile] avva.livejournal.com
Я их просто не знаю, как и сам C#. На вопрос "почему нет" подозреваю, что ответ "слишком сложно, или не хочется из соображений совместимости, делать нужные изменения на уровне JVM". Джавовские дженерики вообще не требуют изменений на этом уровне.

(no subject)

From: [identity profile] selfmade.livejournal.com - Date: 2010-05-23 05:27 am (UTC) - Expand

(no subject)

From: [identity profile] ilyabo.livejournal.com - Date: 2010-05-22 11:22 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 01:06 pm (UTC) - Expand

(no subject)

From: [identity profile] ilyabo.livejournal.com - Date: 2010-05-22 07:12 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 09:32 pm (UTC) - Expand

(no subject)

From: [identity profile] skipy-ru.livejournal.com - Date: 2010-05-25 08:11 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-25 08:34 am (UTC) - Expand

(no subject)

From: [identity profile] skipy-ru.livejournal.com - Date: 2010-05-25 09:43 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-25 09:48 am (UTC) - Expand

(no subject)

From: [identity profile] intracer.livejournal.com - Date: 2010-09-30 09:19 pm (UTC) - Expand

(no subject)

From: [identity profile] plakhov.livejournal.com - Date: 2010-05-24 09:47 am (UTC) - Expand

(no subject)

From: [identity profile] intracer.livejournal.com - Date: 2010-09-30 09:08 pm (UTC) - Expand

Date: 2010-05-22 04:56 am (UTC)
From: [identity profile] ygam.livejournal.com
Ты читал статьи Эндрю Кеннеди про генерики?

Date: 2010-05-22 07:45 am (UTC)
From: [identity profile] avva.livejournal.com
Странно, у меня не открывается ссылка - но нет, не читал.

(no subject)

From: [identity profile] mkazantsev.livejournal.com - Date: 2010-05-22 01:31 pm (UTC) - Expand

(no subject)

From: [identity profile] ygam.livejournal.com - Date: 2010-05-22 03:34 pm (UTC) - Expand

Date: 2010-05-22 05:27 am (UTC)
From: [identity profile] javax-slr.livejournal.com
Одним из главных преимуществ Джавы по сравнению с C++ было именно grokability исходного кода средним программистом: посмотрев на исходник какого-то класса, который он раньше не видел, средний программист на Джаве - не гуру, не хватающий звезды с неба итд. - мог сказать, что делает каждая строка и зачем это нужно.

Полностью согласен. И практически все нововведения в язык после 1.2 уменьшают это преимущество. И autoboxing, и, теперь вот Closures засовывают

Date: 2010-05-22 06:25 pm (UTC)
From: [identity profile] hervejoncour.livejournal.com
ну на самом деле что Autoboxing, что Unboxing, с моей точки зрения, использовать не имеет смысла. Under the hood происходит тот же конвершн, что и раньше , только теперь читать действительно сложнее.

Date: 2010-05-22 06:19 am (UTC)
From: (Anonymous)
По-моему, внесение дженериков в Джаву было огромной ошибкой. Главная польза от них - строгая типизация коллекций - не оправдывает той огромной цены, которую пришлось заплатить: сложностью языка, читабельностью и понимабельностью кода.

Нужно различать сложность полной спецификации языка и сложность того подмножества, на котором пишется почти весь код. На практике почти всегда использование generics не идёт дальше чего-то вроде ArrayList<MyClass>, а это читабельности помогает, хотя и бывает уж очень многословно:

private final AtomicReference<Map<Key, List<Value>>> mymap = new AtomicReference<Map<Key, List<Value>>>(new HashMap<Key, List<Value>>());

А JLS полностью всё равно мало кто понимал. :)


Одним из главных преимуществ Джавы по сравнению с C++ было именно grokability исходного кода средним программистом: посмотрев на исходник какого-то класса, который он раньше не видел, средний программист на Джаве - не гуру, не хватающий звезды с неба итд. - мог сказать, что делает каждая строка и зачем это нужно. Дженерики это свойство языка с помпой похоронили.

Почти согласен с первым утверждением, но скорее сказал бы что Java была what-you-see-is-what-you-get, во всяком случае, в гораздо большей степени, чем C++ и C. Мне кажется, что это свойство одинаково важно как программистам "от сохи", так и изощрённым умам -- сюрпризы никому не нравятся.

Увы, это постепенно ослабляется, но generics тут играют не большую роль, чем такая банальная вещь, как autoboxing.


Можно ли было добиться той же пользы, что дали дженерики, менее разрушительными способами? Пусть не той же, но главной ее части, мне кажется, можно было. Скажем, какая-нибудь аннотация в момент создания коллекции, подсказывающая компилятору, что там должно быть.

Объявления типов суть такие аннотации. Ужасные wildcards нужны, чтобы обслужить ко- и контра-вариантность, это не зависит от того, оформлена ли спецификация типа джавской аннотацией, или ещё как. Или я Вас неправильно понял. Можно было бы отказаться от учёта ко- и контра-вариантности, тогда Джаву ругали бы за это. :)

(Интересно сравнить со Scala, где спецификация "вариантности" живёт в объявлении класса или трейта коллекции -- выглядит разумно, но я пока недостаточно кода написал, чтобы судить.)

Евгений.

Date: 2010-05-22 09:52 am (UTC)
From: (Anonymous)
Wildcards это экзистенциальные типы, контравариантности в них нет, только ко-. Я только недавно понял, насколько это замечательная штука и как она упрощает жизнь по сравнению с C++ — в C++ для выражения того же самого приходится вводить обертки, наследование, делегацию и всякую прочую ерунду.

(no subject)

From: (Anonymous) - Date: 2010-05-22 11:56 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 03:31 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 02:38 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-22 07:54 pm (UTC) - Expand

Date: 2010-05-22 07:43 am (UTC)
From: [identity profile] vladekk.livejournal.com
Теперь хорошо бы вы прочитали то же самое про C# и сравнили впечатления :-)

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

В C# вместе с лямбдами и extension методами это позволило сделать типизированное указание каких-то вещей везде где захочется. (Синтаксис, правда, не всегда совсем уж приятный).

Вот такой код, например, выведет ссылку на метод Index класса-контроллера SearchController с текстом "CHANGE SEARCH". (это из ASP.NET MVC)

Html.ActionLink(sc => sc.Index(), "CHANGE SEARCH")


При этом всё типизированное - я могу сделать рефакторинг любой части, и код не сломается.

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

Хороший пример - linq в c#. Для многих простых случаев очень удобно. Чтобы его использовать, знать, что там внутри строится дерево выражений, необязательно.

Date: 2010-05-22 07:44 am (UTC)
From: [identity profile] vladekk.livejournal.com
хм, lj проглотил кусок
вместо квадратных скобок угловые
Html.ActionLink[SearchController](sc => sc.Index(), Html.Resource("CHANGE SEARCH"))

Date: 2010-05-22 08:06 am (UTC)
From: [identity profile] vladekk.livejournal.com
И ещё такая мысль: может быть, создателям Java стоило сделать сразу два языка: для средних и для продвинутых разработчиков.
А то они к джаве прикручивают всякие фичи, но как-то неуверенно и криво. Генерики, замыкания, type inference.

С другой стороны, майкрософт сделала два языка в дотнете, и тот, что считается "проще" (VB.NET) стал просто second-class citizen - инфы меньше, инструментов меньше, новые платформы от в первую очередь делают поддержку C# и т.д. (Правда, по возможностям VB.NET не сильно отличается от C#, так что проще ли он - большой вопрос)

Date: 2010-05-22 12:38 pm (UTC)
From: [identity profile] pheophan.livejournal.com
Три языка - F# еще

(no subject)

From: [identity profile] hervejoncour.livejournal.com - Date: 2010-05-22 06:19 pm (UTC) - Expand

(no subject)

From: [identity profile] vladekk.livejournal.com - Date: 2010-05-22 06:21 pm (UTC) - Expand

(no subject)

From: [identity profile] pheophan.livejournal.com - Date: 2010-05-22 06:21 pm (UTC) - Expand

(no subject)

From: [identity profile] hervejoncour.livejournal.com - Date: 2010-05-22 06:43 pm (UTC) - Expand

Date: 2010-05-22 09:54 am (UTC)
From: [identity profile] migmit.vox.com (from livejournal.com)
Ой. Не ожидал, совсем.

Дженерики, всё-таки, это новая языковая возможность. Совсем новая. Скажем, шаблоны C++ язык не расширяют, это такой препроцессор на стероидах. А дженерики жабы - это уже настоящий параметрический полиморфизм. Неполный (очень), но честный. Уже огромная польза.

Я слышал, вообще хотели одно время сделать вариант жабы с дженериками и интерфейсами, но без наследования. ИМХО, это было бы очень интересно. Увы, не сложилось.

> зачем в Джаве класс Enum определяется, как Enum<E extends Enum<E>>

А там так сделано? Если да, то это очень правильно.

Причиной тому - ООП-шная манера складывать методы туда же, куда и данные. Соответственно, если какому-то методу интерфейса нужен, кроме this, ещё один аргумент того же типа (скажем, если тип - это вектор, а метод - скалярное произведение), приходится передавать ему этот тип в качестве аргумента дженерика.

Разумеется, гораздо проще написать
class Vector a where scalarProduct :: a -> a -> Float
чем
interface Vector<A extends Vector<A>> {float scalarProduct(A second);}
но реально это одно и то же.

Кстати, на жабе я не пишу.
(deleted comment)

Date: 2010-05-22 01:57 pm (UTC)
From: [identity profile] avva.livejournal.com
Я люблю динамические языки, а на Питоне в последнее время пишу ежедневно; вообще говоря, я всегда предпочту Питон Джаве, если нет важных причин выбрать наоборот. На мой взгляд, при разумном юнит-тестировании, >90% недостатков утиной типизации снимаются, а преимущества остаются. Справедливости ради, надо отметить, что я не работал над питоновскими проектами с >100kloc кода, а над Джавовскими работал.

Date: 2010-05-22 01:06 pm (UTC)
From: [identity profile] cousin-it.livejournal.com
У меня примерно то же впечатление было, когда generics появились и я перестал писать на Java =)

Вот я сейчас пишу на языке haXe, который компилируется в байткод для Flash. Во флеше нету параметризованных типов, а в haXe есть, и работают совершенно просто и понятно. Не знаю, почему в Java не могли сделать примерно то же самое.

Date: 2010-05-22 03:27 pm (UTC)
From: [identity profile] itman.livejournal.com
Главное ведь то, что у дженериков почти нулевой эффект на рантайм, поэтому необязательно было вносить их глубоко в ткань языка, so to speak; подсказки компилятору достигают схожей цели

Да, в отличии от Си++, где они дают выигрыш в производительности.

Date: 2010-05-22 03:36 pm (UTC)
From: [identity profile] avva.livejournal.com
Почти никогда реально не нужный, но это уже другая тема.

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-05-22 04:33 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-05-22 04:39 pm (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-05-22 06:24 pm (UTC) - Expand

(no subject)

From: [identity profile] plakhov.livejournal.com - Date: 2010-05-24 10:00 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 04:01 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-05-22 04:31 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 04:58 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-05-22 05:05 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-22 05:25 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 01:51 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-23 02:08 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 02:44 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-23 02:58 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 03:57 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-23 04:11 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-23 08:00 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-23 09:16 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-24 02:37 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-24 03:26 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-24 04:37 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-24 04:58 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-24 02:42 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-25 08:32 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-25 03:32 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-25 05:29 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-26 03:11 pm (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-26 04:50 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-27 08:25 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-27 08:28 am (UTC) - Expand

(no subject)

From: [identity profile] migmit.vox.com - Date: 2010-05-27 05:08 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-05-24 04:46 am (UTC) - Expand

Date: 2010-05-22 06:50 pm (UTC)
From: (Anonymous)
> (disclaimer: я редко и мало пишу на Джаве по-русски, и не эксперт в ней)

fixed

Date: 2010-05-22 06:51 pm (UTC)
From: (Anonymous)
s/на Джаве/о Джаве/

Date: 2010-05-24 02:04 pm (UTC)
From: [identity profile] meshko.livejournal.com
Ну и чтобы два раза не вставать -- что Вы думаете о добавлении closure в Джаву?
Page 1 of 2 << [1] [2] >>

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 29th, 2025 06:48 pm
Powered by Dreamwidth Studios