Как стать автором
Обновить

Комментарии 113

>Основная возможная проблема это потеря читаемости кода при большом числе операций производимых над коллекцией.

Чушь, такая чушь.
А мне не нравится то, что убрали тип из выражения.
list.getStream().filter(f -> f.getAge() > 21)

Все это упрощает написание, но усложняет чтение. Да еще и нельзя узнать или быстро перейти в определяющий тип f. И хуже того, если поменяется тип списка при рефакторинге, а имена методов совпадут, то возникнет неприятный эффект коллизии.
Объявление типа — лишние символы в коде. IDE поможет определить тип.
Программы пишутся не для того, чтобы их понимали компьютеры, а для того, чтобы их понимали люди.
Все же не люди, а программисты. Ничто не мешает в конкретной команде/организации иметь style guide, запрещающий опускать тип аргумента. А так, вообще, тип если что поможет быстро определить IDE, ну и переменные/аргументы надо называть так, чтобы возникало как можно меньше вопросов, вот и все.
Если смотреть для чего пишутся программы, то программы пишутся для того, чтобы их понимали люди при помощи IDE;-) И у языков со статической типизацией типа Java здесь есть большое преимущество;-)
Кстати, это относится и к умолчательной реализации интерфейсных методов.
Вы знаете, уже сколько лет пишу на C#, где такие штуки уже давно существуют, никаких проблем нет. Это миф, что теряется читаемость.
Ничто не мешает написать
list.getStream().filter((Person f) -> f.getAge() > 21)
В том же C# уже давно есть LINQ с лямбдами и выводом типов. По моему опыту, код работы с коллекциями в таком стиле проще пишется, лучше читается, и менее подвержен ошибкам. Это обкатаная технология, которая есть во большинстве мейнстрим-языков. Тут не о чем переживать, уверяю тебя.
Скажите, а в list.add(f), вас не смущает отсутствие явного указания типа элементов list? Если нет, то в чем именно разница?
Вы действительно не видите разницы в объявлении f?
Я не вижу разницы в том, является ли это объявлением, или нет. Где-то там есть и объявление list тоже, и в нем явно указан тип элементов. Зачем его постоянно повторять при действиях над этим объектом? И неужели при чтении кода неочевидно, что в list.filter(f -> ...) тип f — это тип элемента?
Это задача IDE. В .NET как-то с этим живут и не горюют.
Да помойму тут просто не понимание как это работает, и что такое f.
Не могу не процитировать:

Java 8 has been influenced by Scala much more than how Scala has been influenced by Java (@mariofusco)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Откуда столько ссылок на Scala? Все эти «нововведения» уже давно придуманы, и в большинстве своем даже не Мартином.

Java является самой мощной промышленной платформой и развитие ее стандарта влияет практически на все крупные компании. Глупо ожидать тут гонки за «плюшками».

Многие не понимают, что Java — это больше про JVM и платформу, а не про то, как ставить стрелочки — "->" или "=>". Лямбду хотели ввести еще в 7, но отказались — и правильно. На тот момент это был всего лишь синтаксический сахар на абстрактными классами.
Поддержу. При всей моей либви к Scala та же реализация лямбд в Java 8 — не выглядит как копия со Scala.

Во-первых поддержка в со стороны jvm.
А во-вторых сама идея Functional Interfaces хоть по началу и выглядит отталкивающе, но привыкнув понимаешь ее гениальность. Они не просто ввели лямбды, но сделали их совместимыми с огромным количеством уже существующих библиотек.
На самом деле Project Lambda начал с намного более амбициозного дизайна — например, там были полноценные function types и throws-параметры у дженериков (для строго типизированного прозрачного проброса исключений high-order functions). Но в процессе дизайна практически все плюшки выпилили.

А в Java 7 лямбды не попали просто потому, что тогда дизайн был еще очень далек от завершения.
Но в процессе дизайна практически все плюшки выпилили.
Может быть, в Java 10 добавят?;-)
Задумайтесь, почему их выкинули — может быть, отпадут лишние вопросы.
С одной стороны, если Java продолжит развиваться и реализовать все вокруг лябмда-выражений, как сделали в Scala, тогда возможно не будет надобности в Scala.


Ну это как-то слишком категорично. Java 8 даже до C# не дотянет по удобству и лаконичности. А уж со Scala ей не тягаться. Лямбды — это хорошо, но не все. В верхних двух ответах к этому вопросу перечисленно множество других преимуществ Scala.

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


Что-то не уверен…
… насчет «большинства» :-)
Большинство, как правило, об этом просто не задумываются.
Так понял, что новые Stream'ы — это эдакий LINQ с путанным названием. Поправьте, если неправ.
А вообще, читая статью, не покидало ощущение, что Java смотрит скорее в сторону C#, нежели Scala. Подразумеваю именно вектор развития, а не источник появления новых фич.
Стримы — это элементы ФП над последовательностями. Путанное название и реализация как раз у Microsoft, впрочем, как всегда.
Хм, странно. Всегда думал, что Stream подразумевает поток данных. :)
Ну да. В чем проблема, что странно?
Это я про потоки ввода/вывода.
Да, есть пересечение по названиям, возможна путаница, что поделаешь. А слово «stream» — стандартное для обозначения такого рода объектов в ФП.
Мне кажется «flow» подходит больше
Ленивые потоки как идиома известны еще со времен LISP. И название им streams. И LISP — семейство гибридных языков, так что эту идиому нельзя назвать чисто функциональной.
flow не подойдёт, потому что flow — это скорее процесс «течения», в отличие от stream, который как раз есть сущность этого самого течения.
Тут ещё надо вспомнить, что в русском языке потоки ещё могут означать потоки выполнения, те что threads…
Но, имхо, I/O streams и streams данных достаточно различаются, и по контексту всегда можно понять, что есть что. То же касается и потоков в русском языке.
В русском языке есть термин «поток данных» = «stream».
Так что название «streams» вполне корректное также с точки зрения перевода.
«поток данных» — это более общая абстракция, чем «поток ввода/вывода».
Как то IEnumerable и IQueryable понятней при работе с наборами данных. Так же как и AsParallel() более читабелен.
Несмотря на то, что Stream стандартен с точки зрения ФП, не означает что он уместен в основном синтаксисе Java.
Пока что это нововведения выглядят как не очень удачная попытка скопировать LINQ.
Смотрел на Java с точки зрения переезда с C#, очень ждал аналога LINQ, но такое «кусочничество» пока отталкивает :\
Честно говоря, я в LINQ и вообще C# разбираюсь как баран в апельсинах, и на мой незамыленный взгляд вы с exvel видите тут «след C#» просто потому, что пишете на нем. А я тут вижу просто базовые функциональные примитивы работы с последовательностями, что отнюдь не rocket science, но раньше не было и этого. Сказать, что тут копируют C#, можно на абсолютно тех же основаниях, что и JavaScript, Scala, Python, Ruby, Haskell, или любой другой современный язык с элементами ФП.
LINQ немного больше чем просто кусочек ФП ;)
Я год проработал Ruby разработчиком и там мне очень не хватало LINQ…
При работе с коллекциями в самом деле очень удобно написать personList.Where(p=>p.Age>31) вместо list.getStream().filter((Person f) -> f.getAge() > 21). Хотите параллельно — AsParallel() и тд. Но вектор развития тяготеет к C#/.Net. Тот же аналог using блока — «try-with-resources» в 1.7. Может в 1.9 async будет ;)

Просто не покидает ощущения, что нет четкого вектора развития, что печально. ИМХО.

Слабо знаком с c#, что есть в LINQ чего нет в руби? Пример выше в руби можно записать как person_list.select{|p| p.age > 31 }. В чем плюс LINQ?
В LINQ потом из этого (если операции проводятся над IQueryable) будет построено ExpressionTree, которое может быть преобразовано, к примеру, в SQL.
Вы пробовали Sequel?
Sequel — только для бд. Это лишь частный случай применения.
А вот ExpressionTree вы можете не только в SQL разложить. Плюс их можно налету модифицировать.
В свое время мне понравилась идея добавления поведения объекту типа acts_as_paranoid и тд. На основе ExpressionTrees и декораторов сделал то же самое — IActsAsParanoid ;), но при этом, могу это разложить как на коллекцию объектов в памяти, так и на запрос в БД.
Вот тут интересная статья — community.bartdesmet.net/blogs/bart/archive/2009/08/10/expression-trees-take-two-introducing-system-linq-expressions-v4-0.aspx
каким это образом работа с массивами и бд в руби слабее LINQ?
Нет полноценных ExpressionTree. Я видел попытки повторить это но ощущения от этого были как от очень хрупкого карточного домика. Просто ИМХО.
Если есть возможность получить исходный код метода или блока (а говорят в Ruby 1.9 она есть), то можно вполне элегантное решение сделать. Дерево будет строиться не в процессе компиляции (хотя Ruby и так не компилируемый язык), а в процессе исполнения.

Т.е. пишем метод, который из блока, переданного в метод, строит AST из исходного кода этого блока. Дальше достраиваем это дерево с помощью цепочек вызовов. Профит.
Можно сделать что угодно, но зачем? Даже в том же PHP есть подобное (http://habrahabr.ru/post/121976/).
Другое дело, что Microsoft конкретно так постарались, например, над тем же linq2sql, чтобы вообще избавить конечного пользователя от головной боли при проектировании связки база<->приложение и дать возможность удобно, быстро, качественно и не обращая на возможные узкости применения этой технологии (которой имхо вообще нет в случае с linq*) писать код. Пока ни один язык\платформа, с которой я сталкивался, не дает такой гибкости и легкости разработки, какую дает .NET.

Прошу не принимать меня за ".net-люба". Большую часть времени я работаю именно с Java и мне действительно рад тем ништякам, которая нам даст J8.
Я имею ввиду, что на Ruby и JS (TypeScript или CoffeeScript, чтоб было еще дотнетнее) можно сделать полноценный LINQ как в .NET, без всяких магических строк и с ExpressionTree.

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

Ruby:
DB.Persons.select{|p| p.age > 31 }


JS:
DB.Persons.select(function (p) { return p.age > 31; });


TypeScript:
DB.Persons.select(p => p.age > 31 );

LINQ не только для бд=) Очень удобно работать с коллекциями особенно, если надо провести сложную выборку с join и тд. Причем для сложных запросов можно пользоваться не MethodChain вызовами, а по сути просто написать запрос:

var result = from t in ints1
join x in ints2 on (t + 1) equals x
select t;
Выше поэтому и писал, что не копируют C#, а берут вектор развития. Стримы-Linq, лямбды, функ.интерфейсы-методы расширения. Это все направление движения, которое уже удачно обкатано в C#. Ведь языки, в отличие от других, сильно похожи. Понятное дело, что сами фичи изобретены не в Майкрософт.
>>Честно говоря, я в LINQ и вообще C# разбираюсь как баран в апельсинах, и на мой незамыленный взгляд вы с exvel видите тут «след C#» просто потому, что пишете на нем

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

У меня лично твёрдое убеждение, что качество кода, написанного на любом мэйнстримовом языке, мало кореллирует с синтаксическим сахаром, доступным в этом языке.
Синтаксический сахар — это удобство и читаемость. Экономия времени при сопровождении.
Когда есть сахар в языке, многие сложные конструкции можно сильно сократить.
Называть ли код с сахаром качественнее аналогичного без оного? Я бы сказал, что зависит от приоритетов при разработке. Если нужна оптимизация, то сахар может даже помешать. Но в большинстве повседневных задач, скорее, влияет положительно.
Я скорее имею в виду, что действительно хороший программист и без сахара найдёт способ написать понятно и корректно. А 90% кода что с сахаром, что без сахара, будет читаться и работать паршиво.
С этим сложно поспорить. :)
>>и без сахара найдёт способ написать понятно и корректно
понятно и корректно — но только в рамках заданного языка. без синтаксического сахара.
Ну вот хоть тут будет супер-пупер программист на асме, но даже середнячок на шарпе клиента к БД напишет понятнее.
И нормальный программер на OCaml напишет какой нить парсер в 100 раз понятнее, чем это сделает сишник.
У каждого языка есть ниша, в которой он выглядит лучше других :-) Иначе он становится мертвым.
Это далеко не LINQ — ничего не было интегрировано в язык, т.е. это чисто библиотечная функциональность.
Суть стримов раскрывается в цитате из javadoc:
A sequence of elements supporting sequential and parallel bulk operations. Streams support lazy transformative operations (transforming a stream to another stream) such as filter and map, and consuming operations, such as forEach, findFirst, and iterator. Once an operation has been performed on a stream, it is considered consumed and no longer usable for other operations.

For sequential stream pipelines, all operations are performed respecting in the encounter order of the source, if the source has a defined encounter order. For parallel stream pipelines, unless otherwise specified, intermediate stream operations preserve the encounter order of the source, and terminal operations respect the encounter order of the source, if the source has an encounter order.
А что было интегрировано в C# для поддержки LINQ, помимо добавление расширяющих методов?
Как минимум замыкания и цитирование. Допустим, первое как-то поддержено в Java, но второго даже нет в планах.
Еще можно посчитать доработку парсера под linq-запросы.
А замыкания к LINQ каким боком? Хотяяя… Чтобы не сыпать вопросами, не подскажите, где можно вразумительно почитать про реализацию?
Не совсем про реализацию, но читал в свое время «LINQ in Action». И MSDN, конечно.
А что такое цитирование в C#? Я бы сказал, что основные доработки в C# выразились в доработках компилятора (парсинг, расширение использования утиной типизации, пр.).
Квацитирование — преобразование выражения в ExpressionTree. Попробуйте без этой плюшки сгенерировать, например, SQL-запрос из from p in persons where p.Name == "John" select p;
Ок, понятно, иными словами создание AST из linq и сохранение структуры данных. Еще, из конкретики, extension methods добавили. У них, конечно, область применения широка, но они явились способом поддержки linq в базовой библиотеке.
Та часть LINQ, которая про работу с коллекциями — она точно такая же библиотечная функциональность. По сути в Java вместо extension methods приделали functional interfaces. Остальное — лямбды, замыкания и прочее — такое же. А Stream, как я понимаю — это тот же IEnumerable. Но в целом LINQ с его expression trees и специальным синтаксисом помощнее, да.
Странное заключение.

Стримы — как раз больше про удобство, чем про магическое ускорение существующего кода. Для 99.99% ситуаций модель распараллеливания стримов с разворачиванием fork-join пула — явный overkill. Чересчур универсальное решение, чтобы быть быстрым. Если кому-то при обработке каких-то коллекций действительно нужна скорость и мощь всех имеющихся ядер — уже написанный руками код почти наверняка работает быстрее, чем будут работать стримы.

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

То, что вызывает опасения, так это функциональные интерфейсы. При не правильном использовании может вызывать кучу головной боли.
???

Про HashMap можно было упомянуть новые удобные функции. Атака хеш-таблиц с корзинами для разрешения коллизий — это конечно мега распространенная ситуация…
Для 99.99% ситуаций модель распараллеливания стримов с разворачиванием fork-join пула — явный overkill.

Новый ForkJoinPool теперь использует work-stealing планировщик и рандомизованные очереди, что по некоторым замерам увеличило производительность более чем в 10 раз.
Extension Methods — это не хилая такая фича языка. Подобное есть во многих языках, но в Java нет и не обещают.

А по поводу что еще…

var l2 =
    (
        for e1 in list1
        join e2 in list2 on new {e1.Field1, e1.Field2} equals new {e2.Field1, e2.Field2}
        where e1.IntField > 0
        select e2.Field3
    ).ToList()


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

exvel перенес вопрос выше.
Интересно, почему в статье назвали интерфейсы с default-методами функциональными? Функциональный интерфейс — это просто интерфейс, у которого есть один абстрактный метод, вот и всё. default-методы к функциональности интерфейса непосредственного отношения не имеют.
О! Первый возглас в числе комментов.
Хотите ответ — а назвали так, потому, что автор оригинальной стать не шарит! Да и переводчик тоже, иначе исправил бы.
Да и авторы фичи, которые предлагают ставить аннотацию @FunctionalInterface на интерфейсах с дефолт-методами тоже.
Жаль, что Java так инертна в развитии — думал перейти с C# на Java но даже 8ка пока не мотивирует :-(
Перейдите на другой JVM-язык, тут вам и JRuby, и Scala, Clojure, Groovy. Любой из этих языков получает доступ ко всему codebase java. В проектах эти языки можно совмещать с Java, как душе угодно.

Я, например, перешел на Scala, не нарадуюсь.
Нет смысла менять шило на мыло. Если вам нужна JVM, смотрите в сторону Scala или Clojure. А джаву на уровне библиотек освоите и хватит.
Ну вообще-то люди не просто так переходят с одной платформы на другую.
И если для вас самое главное это синтаксический сахар, то скорее всего оно вам абсолютно не нужно.

Не для холивара.
Я в какой-то момент окунулся в платформу NET. Поработал с VS и прочим рабочим окружением разработчика.
И понял, что никакие синтаксические плюшки C# не перевесят весь этот глобальный ужас рабочего окружения связанного с NET.
А что не так с окружением?
Только не надо на мои слова бросаться как на амбразуру)
Это всего лишь впечатления от работы с NET стеком.
Просто после Java, все что связано с NET вызывало удивление.

Ну во первых, это IDE. Этот монстр, даже в экспресс версии, устанавливается на несколько гигабайт.
После IDEA, я просто тихо офигевал от мелочей о которых раньше просто не задумывался.
Простейший пример, банальнейший, в java мире, все IDE что я видел, по умолчанию сохраняют вывод консоли в отдельном окне и даже если программа вылетела, можно полистать и посмотреть что там происходило.
VS же отлично закрывает свою консоль и в результате нихрена непонятно где искать вывод консоли после вылета приложения. Подчеркну для тех кто на бронетехнике, я говорю про поведение по умолчанию. Понятно что всегда можно что-то сделать. Даже написать свою IDE. Но таких вот мелочей слишком уж много в процессе выяснялось.
Потом вся виндовая инфраструктура VCS, интернет серверы и прочее. Проблемы с версиями NET и т.д.
Опять же windows only продукты. Чтобы писать под NET, только винда, серверы только винда и т.д. со всеми вытекающими. Да, для кого-то это наоборот жирный плюс, например для продажников ;)
Опять повторюсь для тех кто на бронетехнике, это не означает, что нет mono, но речь сейчас не о нем.
Ну и просмотр цен на все это непотребство завершает картинку.

В общем ощущения были, что мне загипсовали руки и заставили вот так работать))
Опять же повторюсь для тех кто еще не слез с бронетехники. Все мои слова не означают, что на NET стеке ничего невозможно разработать. Это всего лишь общие впечатления после небольшого погружения в мир NET.

P.S. Ну а после ознакомления со Scala, вообще стало непонятно, зачем нужен C# ))
Оно, видимо, не рассчитано на ваш сценарий использования.

Там, где я работаю, стек технологий MS используется весьма удачно: в VS очень удобно объединяется работа с кодом, системой контроля версий, таск-трекером, работой с билд-сервером. В общем со всем, что требуется для работы. Это требуется настраивать (1 раз), это не подходит для индивидуального разработчика, но не на таких и ориентировано.

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

А про скалу… на ней пока мало кто пишет. Жаль, конечно, но что поделать.
Да и поддержка IDE не идеальна. Несомненно, что для Scala IDE не столь необходима, как для Java. И в JetBrains проделали великолепную работу для поддержки Scala. Но будим честны: IDEA не понимает сложный scala-код. Как только появляется scalaz или path-dependent types идее плохеет.

Да и в плане GUI Java-стек в роли догоняющих. Я надеюсь на JavaFX (и ScalaFX), но это пока новая, не обкатанная технология.
Да, вы все верно поняли.
Оно именно для моих целей не удобно.
Да Решарпер отличное дополнение. Но вот… купить студию за ~1000$ + еще решарпер ~200$…

А на скале уже и яндекс щас пишет свои сервисы.
Так что времена «пока мало кто пишет» прошли.

Если подвести итог того что я видел, на Scala люди пишут свои продукты.
Т.е. когда люди заинтересованы в собственной эффективности.
Для заказчиков, т.е. оутсорс, продают стандартные известные вещи, которые проще и выгоднее продать.
Но вот… купить студию за ~1000$ + еще решарпер ~200$…

А что поделать? Считайте, что IDE стоит 1200 =)

Так что времена «пока мало кто пишет» прошли.

Я говорю с точки зрения наемного программиста: в Питере мало кто пишет.
Ясно. Ну, видимо, дело привычки. Я, к примеру, давно привык к громоздкости окружения. Все равно ставится один раз.
Про проблемы с версиями не очень понял. Точнее сам не сталкивался за два года.
Насчет консоли, есть окно «Вывод». Оно доступно как во время дебага, так и редактирования кода. Туда скидывается вся инфа по грузящимся сборкам, исключениям, отладочным записям Debug.WriteLine() и основной консоли Console.WriteLine(). Окно очищается только перед запуском отладки, а все записи сохраняются после.
>ужас рабочего окружения связанного с NET.

А мужики-то не знали.
Есть такая фраза «Лучшее враг хорошего».
Понять разницу можно только поработав и с тем и с другим.
Поработал и с тем и с другим, и могу с увереностью сказать, что у вас Синдром утенка.

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

P.S. Насчет IDE это вообще не показатель. т.к. по сравнению со всеми IDE в VS меньше всего багов.(покрайней мере раздражающих)
P.P.S. Консоль по умолчанию не закрывается в VS. Всегото нужно на другую вкладочку переключится.
Про утенка вы мимо))
Если коротко, я начинал с dephi, продолжал C# и сейчас вот Java/Scala.
Да, после нескольких лет Java возникла необходимость опять на NET некоторые вещи сделать.
Отсюда и впечатления.
Мне не нравится Java тем, что решить задачу скорей всего можно не множеством с пособов, а ограничеым числом(совсем не элегантных).

Пример с перегрузкой оператовров. Допустим сумма векрторов и тп.
Ну вы сравнили.
Java это же матерый ынтырпрайз)) там элегантность никого особо не интересует.
Для красоты и элегантности та же Scala используется… или другие JVM языки.
Дак, вот в этом то и беда у каждой предметной области есть свои бизнес-правила. и их приходится реализовывать не так красивои и интуитивно понятно.
IMHO, перегрузка операторов без статической типизации — самоубийство :-)
Хотя при поддержке IDE для языков со статической типизацией (а-ля Java) могли бы и сделать
Я работал с IDEA, VS10/12, Xamarin studio (monotouch). Не вижу каких-то принципиальных жестей ни в одной из этих сред (если уж мы про среды).
Лямбда это конечно сахар, жаль ExpressionTrees нету :(
Вот где прорыв бы был.
чего то я не нашел, а implicitly typed будут введены в java8?
`var` из C#? Нет. Это было бы слишком хорошо, видимо.
ну не только из C#, я насколько понимаю в scala такое тоже есть
Я всего-лишь привел наиболее известную аналогию. Не сомневаюсь, что есть и другие примеры.

И в Scala не такое. Там из-за другого синтаксиса `val` и `var` являются обязательными элементами, а не заменяют имя типа, в отличии от C# и того, что бы могло бы быть в Java.

C#:

int i = 1; // vs.
var i = 1;


Scala:

val i: Int = 1 // vs.
val i = 1


И я не уверен можно ли назвать аналогией `auto` из C++: там, кажется, есть отличия.
Спасибо за разеснение, я что в Scala не силён, что в С++.
Ой, а можете реальный юзкейс из мира джавы привести, где это было бы полезно?
Я правда не знаю, очень интересно.
Вот вам реальный кейс из C# (в Java аналогично):
var elements=collection.Where(x=>x.foo>bar).Select(x=>x.baz);
foreach(var element in elements)
{
    Dosmth(element);
}

Не нужно думать, что за тип у element, компилятор и среда сами его выводят. Т.е. и читать просто, нет загромождения, и в то же время невозможно ошибиться с типом, так как var это все та же статическая типизация. В этом примере, кстати, даже foreach можно в монаду запихнуть, просто не всегда бывает удобно.
Выше уже дали пример кода.

Мне же более наглядным кажется пример вроде такого (C#):

Dictionary<TreeNode<BusinessObject>, IList<TreeNode<BusinessObject>>> childrenByParent = ... а что я вообще собирался сделать? забыл =(


Все имена вымышлены, все совпадения случайны

По моему опыту при правильном именовании тип и так понятен из контекста. И захламлять код декларациями, выглядящими как песня с припевом совершенно излишни.

Или взять Scala. При использовании Scalaz вот такой тип является вполне обычной практикой: ValidationNel[String, List[Category]]. Это если забыть о том, что на самом деле это Validation[NotEmptyList[String], List[Category]]. Кстати, пример из моего кода. И это еще упрощение, на практике вполне возможно будет не String. Подобные типы иногда появляются на две строчки кода и больше ни где не используются — зачем их писать? Там и так все понятно: если в коде используется Validation, то он используется постоянно и не надо об этом каждый раз напоминать.
В общем случае в C++ так же,
auto i = 1;
// or, more like C++11
auto i {1};
Я не разбираюсь в C++11, но помню как меня удивило использование autoв лямбдах. auto тип параметра чтоли… не помню.
В общем случае в C++ так же,
auto i = 1;
// or, more like C++11
auto i {1};



Знаю что это пост 13-го года… Но на случай если кто-то сюда случайно попадет так же как и я.
Ваши 2 выражения не идентичны. В первом случае auto выведется в тип int — все правильно. А во втором в…
std::initializer_list<int>

Такая особенность выведение типов у auto.
Как мне нравится последнее время такая тенденция. Берется статья и переводится.
Блин, и тут даже не выйдет объяснить автору, что он балбес. Ибо в любом случае стрелки на автора оригинала, и спорить нужно там.
А тут перевод. Перевод статьи, автор которой совсем не разбирается в теме.
Можно пойти по ссылке на статью-оригинал и отписаться там :)
Ага, и при этом теряется русскоязычная часть аудитории, ибо 90% людей не пойдут за оригиналом, предпочитая отписываться на месте. Еще бы комментарии автоматически постились в оригинальный блог… :-D Но чудес не бывает, до «Web 4.0» мы еще не дожили.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории