Является ли библиотека коллекций Scala 2.8 «самой длинной запиской о самоубийстве в истории»?

829

Я только начал смотреть на Scala повторная реализация библиотеки коллекций, которая приближается к ближайшему 2.8 релиз. Те, кто знаком с библиотекой из 2.7, заметят, что библиотека с точки зрения использования мало изменилась. Например...

> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)

... будет работать в обеих версиях. Библиотека в высшей степени пригодна для использования: на самом деле это фантастика. Тем не менее, те, кто ранее не знаком с Scala и выкапывают, чтобы почувствовать язык, теперь должны понимать сигнатуры методов, такие как:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

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

  • Разве это не приведет людей к Scala?
  • Это даст Scala плохую репутацию в коммерческом мире как академическую игрушку, которую могут понять только посвященные аспиранты? Являются CTO, и руководители программного обеспечения будут отпугивать?
  • Была ли библиотека перепроектирована разумной идеей?
  • Если вы используете Scala на коммерческой основе, вы беспокоитесь об этом? Вы планируете немедленно принять 2.8 или подождать, чтобы узнать, что произойдет?

Стив Йегге после нападения Scala (по ошибке по-моему) за то, что он считал своей сложной типовой системой. Я беспокоюсь, что у кого-то будет полевой день, распространяющий FUD с этим API (подобно тому, как Джош Блох испугал JCP из добавления закрытий на Java).

Примечание. Мне должно быть ясно, что, хотя я считаю, что Джошуа Блох влиял на отказ от BGGA закрывает предложение, я не приписываю это ни к чему, кроме его честных убеждений, что это предложение представляет собой ошибку.


Несмотря на то, что моя жена и коллеги продолжают говорить мне, я не думаю, что я идиот: у меня есть хорошая степень по математике из Университет Оксфорд, и я программировал коммерчески почти 12 лет и в Scala около года (также коммерчески).

Обратите внимание, что название воспалительного субъекта - цитата

  • 10
    фуд - это просто страх, неуверенность и сомнение - я думаю, что это довольно ясно выражает тон речи Джоша Блоха, который, как мне кажется, тоже вполне обоснован и аргументирован, и т. д. Если вы видите изменения, я изначально не делал фуд, потому что Я не хотел подразумевать пять коннотаций
  • 3
    Я должен сказать, что вернул его обратно, потому что я волнуюсь, что FUD будет распространяться о скале, и я только говорю, что это похоже на то, что Блох делал в своей презентации. (Где один из его аргументов был «почему бы просто не использовать scala»)
Показать ещё 13 комментариев
Теги:
scala-collections
scala-2.8

18 ответов

768
Лучший ответ

Надеюсь, это не "записка о самоубийстве", но я вижу вашу точку зрения. Вы нажимаете на то, что одновременно является и силой, и проблемой Scala: ее расширяемость. Это позволяет нам реализовать большинство основных функций в библиотеках. В некоторых других языках будут созданы последовательности с чем-то вроде map или collect, и никто не должен видеть все обручи, которые должен выполнить компилятор, чтобы заставить их работать плавно. В Scala все это в библиотеке и, следовательно, в открытом доступе.

Фактически функциональность map, поддерживаемая сложным типом, довольно продвинута. Рассмотрим это:

scala> import collection.immutable.BitSet
import collection.immutable.BitSet

scala> val bits = BitSet(1, 2, 3)
bits: scala.collection.immutable.BitSet = BitSet(1, 2, 3)

scala> val shifted = bits map { _ + 1 }
shifted: scala.collection.immutable.BitSet = BitSet(2, 3, 4)

scala> val displayed = bits map { _.toString + "!" }
displayed: scala.collection.immutable.Set[java.lang.String] = Set(1!, 2!, 3!)

Посмотрите, как вы всегда получаете наилучший тип? Если вы нажмете Int на Int, вы снова получите BitSet, но если вы наберете Int - String s, вы получите общий Set. Как статический тип, так и представление результата выполнения во время выполнения зависят от типа результата передаваемой ему функции. И это работает, даже если набор пуст, поэтому функция никогда не применяется! Насколько я знаю, нет никакой другой структуры коллекций с эквивалентной функциональностью. Однако с точки зрения пользователя это то, как должны работать вещи.

Проблема заключается в том, что все умные технологии, которые делают это, просачиваются в сигнатуры типов, которые становятся большими и страшными. Но, возможно, пользователю не следует показывать по умолчанию полную подпись типа map? Как насчет того, посмотрела ли она map в BitSet, она получила:

map(f: Int => Int): BitSet     (click here for more general type)

Документы не будут лежать в этом случае, потому что с точки зрения пользователя карта действительно имеет тип (Int => Int) => BitSet. Но map также имеет более общий тип, который можно проверить, нажав на другую ссылку.

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

  • 101
    Я чувствую себя непослушным школьником! Большое спасибо, что нашли время, чтобы ответить здесь. Я думаю, что баланс ответов показал мне, что мне не нужно беспокоиться; будет достаточно людей, которые вообще не запуганы.
  • 161
    Нет, я думаю, что вы были абсолютно правы в этом вопросе. И другие люди будут напуганы, если мы не сделаем что-нибудь с этим.
Показать ещё 17 комментариев
192

У меня нет PhD, ни какой-либо другой степени ни в CS, ни в математике, ни в какой-либо другой области. У меня нет предыдущего опыта работы с Scala или любым другим подобным языком. У меня нет опыта даже с удаленно подобранными системами. На самом деле, единственным языком, на котором я имею больше, чем просто поверхностное знание, в котором даже есть система типов, является Pascal, не совсем известный своей сложной системой типов. (Хотя у него есть типы диапазонов, которые AFAIK практически не имеют другого языка, но это на самом деле не актуально здесь.) Три других языка, которые я знаю, это BASIC, Smalltalk и Ruby, ни один из которых даже не имеет системы типов.

И все же, я вообще не понимаю, как распознать подпись функции map, которую вы опубликовали. Мне кажется, что почти та же подпись, что map имеет на всех других языках, которые я когда-либо видел. Разница в том, что эта версия является более общей. Он больше похож на С++ STL, чем, скажем, на Haskell. В частности, он абстрагируется от конкретного типа коллекции, только требуя, чтобы аргумент IterableLike, а также абстрагируется от конкретного типа возврата, только требуя существования неявной функции преобразования, которая может построить что-то из этой коллекции результата значения. Да, это довольно сложно, но на самом деле это всего лишь выражение общей парадигмы общего программирования: не принимайте ничего, что вам действительно не нужно.

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

Итак, вместо

map :: (a → b) → [a] → [b]

который является традиционной сигнатурой типа для map, он обобщен, чтобы не требовать конкретного List, а скорее как структуру данных IterableLike

map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j

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

map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c

Я признаю, что синтаксис немного clunkier, но семантика такая же. В основном, он начинается с

def map[B](f: (A) ⇒ B): List[B]

которая является традиционной сигнатурой для map. (Обратите внимание, что из-за объектно-ориентированного характера Scala параметр входного списка исчезает, поскольку теперь он является неявным параметром приемника, который имеет каждый метод в системе OO с одним отправкой.) Затем он обобщен из конкретного List к более общему IterableLike

def map[B](f: (A) ⇒ B): IterableLike[B]

Теперь он заменяет коллекцию результатов IterableLike функцией, которая производит, ну, действительно что-то в этом роде.

def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Я действительно считаю, что это трудно понять. Там действительно только несколько интеллектуальных инструментов, которые вам нужны:

  • Вам нужно знать (примерно), что такое map. Если вы дали только подпись типа без имени метода, я согласен, было бы намного сложнее выяснить, что происходит. Но поскольку вы уже знаете, что должен делать map, и вы знаете, какова его подпись типа, вы можете быстро отсканировать подпись и сосредоточиться на аномалиях, например: "почему этот map выполняет две функции как аргументы, а не один?"
  • Вам нужно действительно прочитать подпись типа. Но даже если вы никогда не видели Scala раньше, это должно быть довольно просто, поскольку это действительно просто смесь синтаксисов типов, которые вы уже знаете из других языков: VB.NET использует квадратные скобки для параметрического полиморфизма и использует стрелку для обозначают тип возврата и двоеточие, чтобы разделить имя и тип, на самом деле является нормой.
  • Вам нужно знать, что такое общее программирование. (Это не так сложно понять, так как в основном это прописано в названии: это буквально просто программирование в общем виде). ​​

Ни один из этих трех не должен давать серьезной головной боли любому профессиональному или даже программисту-любителю. map была стандартной функцией почти в каждом языке, разработанном за последние 50 лет, тот факт, что разные языки имеют различный синтаксис, должен быть очевиден для всех, кто разработал веб-сайт с HTML и CSS, и вы не можете подписаться на даже дистанционно связанный с программированием список рассылки без какого-то раздражающего фанатика С++ из церкви Св. Степанова, объясняющего достоинства родового программирования.

Да, Scala является сложным. Да, Scala имеет одну из самых сложных систем, известных человеку, конкурирующих и даже превосходящих языки, такие как Haskell, Miranda, Clean или Cyclone. Но если сложность была аргументом против успеха языка программирования, С++ давно бы умер, и мы все будем писать Схему. Есть много причин, по которым Scala, скорее всего, не будет успешным, но тот факт, что программистам не нужно беспокоиться о том, чтобы включить их мозги, прежде чем садиться перед клавиатурой, вероятно, не будет основным.

  • 35
    @Jorg - это отличный ответ; благодарю вас. Независимо от того, имеете ли вы ученую степень или нет, вы являетесь человеком более ярким, чем я. Единственное, что я имею в виду , так это то, что я понимаю общую картину того, что происходит в сигнатуре метода. Тем не менее, детали все еще сбивают с толку: как That выводится и связывается с типом B являющимся одним вопросом, который возникает в голове. Откуда берутся следствия от того, чтобы быть другим? Даже без этих подробных наблюдений я все еще лично чувствую, что это сложная подпись. Но, очевидно, есть такие люди, как вы, которые совсем не смущаются этим!
  • 47
    Хорошее объяснение, но вы еще больше убедили меня, что сигнатура метода «map» в Scala 2.8 очень сложна.
Показать ещё 13 комментариев
169

То же самое в С++:

template <template <class, class> class C,
          class T,
          class A,
          class T_return,
          class T_arg
              >
C<T_return, typename A::rebind<T_return>::other>
map(C<T, A> &c,T_return(*func)(T_arg) )
{
    C<T_return, typename A::rebind<T_return>::other> res;
    for ( C<T,A>::iterator it=c.begin() ; it != c.end(); it++ ){
        res.push_back(func(*it));
    }
    return res;
}
  • 103
    ... и они говорят, что Скала неясна. Duh!
  • 3
    Aiiieeeee! То же Рахул
Показать ещё 3 комментария
69

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

Что я имею в виду, так это то, что... большинству программистов это не понравится, потому что они их никогда не заметят! Они не читают документацию.

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

Учитывая эти вещи, я думаю, что:

  • Любой (как и большинство людей), который когда-либо сталкивался с такой подписью типа, будет безмолвным Scala, если они предварительно настроены против него, и будет считать его символом Scala power if им нравится Scala.

  • Если документация не улучшена, чтобы предоставить примеры использования и четко объяснить, что такое метод и как его использовать, это может немного уменьшить Scala принятие.

  • В долгосрочной перспективе это не имеет значения. Этот Scala может делать такие вещи, что сделает библиотеки, написанные для Scala гораздо более мощными и безопасными в использовании. Эти библиотеки и рамки будут привлекать программистов, привлеченных к мощным инструментам.

  • Программисты, которые любят простоту и прямоту, будут продолжать использовать PHP или похожие языки.

Увы, Java-программисты в значительной степени задействованы в электроинструментах, поэтому, отвечая на это, я только что пересмотрел свое ожидание внедрения mainstream Scala. Я не сомневаюсь, что Scala станет основным языком. Не C-mainstream, но, возможно, Perl-mainstream или PHP-mainstream.

Говоря о Java, вы когда-нибудь заменяли загрузчик классов? Вы когда-нибудь изучали, что это значит? Java может быть страшно, если вы посмотрите на места, которые создатели фреймворков делают. Это просто, что большинство людей этого не делают. То же самое относится и к Scala, ИМХО, но ранние усыновители имеют тенденцию смотреть под каждую скалу, с которой они сталкиваются, чтобы увидеть, что там что-то скрывается.

  • 10
    As long as they saw some example of how the code works, and the code doesn't fail them in producing the result they expect, they won't ever look at the documentation. When that fails, they'll look at the documentation and expect to see usage examples at the top. Грустно, но правда.
  • 9
    @ gamliela, я не думаю, что нам будет грустно об этом. У знания всегда может быть более одного уровня, и работа и доверие других (проверенные коллегами) в любой системе всегда могут быть использованы, как мы ежедневно используем арифметику и полностью игнорируем страшные алгебры, работающие за ним.
49

Собирает ли это людей на Scala?

Да, но это также предотвратит отключение людей. Я рассматривал нехватку коллекций, которые используют более высокие типы, чтобы быть серьезной слабостью с тех пор, как Scala получила поддержку более высокосортных типов. Это делает документы API более сложными, но на самом деле делает использование более естественным.

Является ли это тем, что Scala плохое имя в коммерческом мире является академической игрушкой, которую могут понять только посвященные аспиранты? Будут ли отстранены руководители и руководители программного обеспечения?

Скорее всего, будет. Я не думаю, что Scala доступен для многих "профессиональных" разработчиков, частично из-за сложности Scala и отчасти из-за нежелания многих разработчиков учиться. Техники, которые используют таких разработчиков, по праву будут испуганы.

Была ли библиотека перепроектирована разумной идеей?

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

Если вы используете Scala на коммерческой основе, вы беспокоитесь об этом? Вы планируете немедленно принять 2.8 или ждать, чтобы узнать, что произойдет?

Я не использую его коммерчески. Я, вероятно, подожду, пока, по крайней мере, пара не вернется в серию 2.8.x, прежде чем даже попытаться представить ее так, чтобы ошибки могли быть сброшены. Я также подожду, чтобы увидеть, как много успехов EPFL в улучшении процесса разработки. То, что я вижу, выглядит обнадеживающим, но я работаю в консервативной компании.

Один из наиболее общих тем "Scala слишком сложный для основных разработчиков?"...

Большинство разработчиков, в основном или других, поддерживают или расширяют существующие системы. Это означает, что большинство из того, что они используют, продиктовано решениями, принятыми давно. Есть еще много людей, которые пишут COBOL.

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

  • 31
    «Это также предотвратит отстранение людей». этот. абсолютно. Scala - первый язык, который делает разработку с чем-то сравнимой с haskell (в силу системы типов) для многих из нас. я не смог бы убедить работу использовать haskell, но у scala действительно есть шанс, и за это я люблю его и буду (когда я думаю, что это имеет смысл) попытаться принять его или, по крайней мере, принять, на работе.
  • 0
    +1 от меня тоже. Учитывая предпосылку, что Scala делает больший упор на глубину и строгость языка, чем на массовую доступность, эти ответы идеально подходят.
Показать ещё 1 комментарий
45

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

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

38

У меня есть степень бакалавра в дешевом американском университете "массового рынка", поэтому я бы сказал, что я попал в середину шкалы пользовательской информации (или, по крайней мере, образования). Я занимался с помощью Scala всего за несколько месяцев, и работали над двумя или тремя нетривиальными приложениями.

Особенно сейчас, когда IntelliJ выпустила свою прекрасную IDE с тем, что IMHO в настоящий момент является лучшим плагином Scala, разработка Scala относительно безболезненна:

  • Я нахожу, что могу использовать Scala как "Java без точек с запятой", т.е. пишу аналогичный код для того, что бы я сделал на Java, и немного выиграл от синтаксической краткости, например, полученной тип вывода. Обработка исключений, когда я вообще делаю это, более удобна. Определение класса гораздо менее подробное без шаблона getter/setter.

  • Время от времени мне удается написать одну строку, чтобы выполнить эквивалент нескольких строк Java. Там, где это применимо, цепочки функциональных методов, таких как map, fold, collect, filter и т.д., Очень интересны для составления и элегантности.

  • Лишь в редких случаях я получаю пользу от Scala более мощных функций: закрытий и частичных (или карри) функций, сопоставления шаблонов... что-то вроде.

Как новичок, я продолжаю бороться с кратким и идиоматическим синтаксисом. Вызов методов без параметров не требует скобок, кроме случаев, когда они выполняются; в случаях, когда в спичечном заявлении нужна жирная стрелка (=>), но есть также места, где вам нужна тонкая стрелка (->). У многих методов есть короткие, но довольно загадочные имена, такие как /: или \:. Я могу получить свой материал, если я переверну немного страниц руководства, но некоторые из моего кода выглядят как Perl или линейный шум. По иронии судьбы, один из самых популярных битов синтаксического сокращения отсутствует в действии: я все время укусаюсь из-за того, что Int не определяет метод ++.

Это только мое мнение: я чувствую, что Scala обладает мощью С++ в сочетании со сложностью и удобочитаемостью С++. Синтаксическая сложность языка также затрудняет чтение документации API.

Scala очень хорошо продуман и блистателен во многих отношениях. Я подозреваю, что многие академики с удовольствием проедут в нее. Тем не менее, он также полон умности и gotchas, он имеет гораздо более высокую кривую обучения, чем Java, и ее труднее читать. Если я сканирую форекс и вижу, сколько разработчиков все еще борется с точными точками Java, я не могу представить, что Scala станет основным языком. Ни одна компания не сможет обосновать отправку своих разработчиков на 3-недельный курс Scala, когда раньше им нужен только курс Java на неделю.

  • 3
    После одной недели курса Java вы готовы к серьезной разработке программного обеспечения! Я не думаю, что Scala пытается занять место Java или когда-либо думает, что это будет следующая Java. Но я думаю, что они могут стремиться к успеху, скажем, Ruby или Python, которые имеют значительную базу пользователей. Вопрос в том, "они облажались?"
  • 1
    Спасибо за то, что сделали мой пост красивее :) Ваш вопрос касался некоторых деталей, добавленных к уже существующей картинке. Если бы я не изо всех сил пытался понять набор функций 2.7, я мог бы понять более тонкие моменты. Мое личное мнение заключается в том, что «обновление» API коллекций лишь добавило немного больше оскорблений к некоторым и без того довольно серьезным травмам. Умные люди, подобные вам, справятся, менее умные люди, такие как я, возможно, уже убежали с криком.
Показать ещё 13 комментариев
30

Я думаю, что основная проблема с этим методом заключается в том, что (implicit bf : CanBuildFrom[Repr, B, That]) идет без каких-либо объяснений. Хотя я знаю, какие неявные аргументы ничего не показывают, как это влияет на вызов. Преследование через scaladoc только оставляет меня более запутанным (некоторые из классов, связанных с CanBuildFrom, даже имеют документацию).

Я думаю, что простой "должен быть неявный объект в области для bf, который предоставляет построитель для объектов типа B в тип возврата That", несколько помог, но это своего рода пьянящее понятие когда все, что вы действительно хотите сделать, это map A to B. На самом деле, я не уверен, что это правильно, потому что я не знаю, что означает тип Repr, а документация для Traversable, конечно, не дает никакого представления.

Итак, у меня остались два варианта, ни один из них не приятен:

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

Я понимаю, что Scala по существу раскрывает мужество того, как эти вещи работают, и что в конечном итоге это дает возможность делать то, что описывает oxbow_lakes. Но это отвлечение в подписи.

  • 2
    Repr является проходимым представлением, т.е. List или Set или Map . Я думаю, что в качестве основы, если вы собираетесь начать смотреть на сигнатуры методов (а не просто использовать методы путем копирования примеров), вы должны сначала понять общий дизайн. ИМХО Скаладок должен быть полон примера использования
  • 10
    Итак, как бы я определил, что имел в виду Repr ? Я ожидал бы объяснения в скаладоке, но это было для меня неочевидно. Я думаю, что это общий шаблон в скаладоке (посмотрите на Actor.react и Actor.receive - мне сказали, и я видел, что они делают совершенно разные вещи, но их скаладок идентичен).
Показать ещё 1 комментарий
22

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

На самом деле все это довольно элегантно. Параметры типа строителя позволяют компилятору выбрать правильный тип возвращаемого значения, в то время как механизм неявных параметров скрывает этот дополнительный параметр от пользователя класса. Я пробовал это:

Map(1 -> "a", 2 -> "b").map((t) => (t._2) -> (t._1)) // returns Map("a" -> 1, "b" -> 2)
Map(1 -> "a", 2 -> "b").map((t) =>  t._2)            // returns List("a", "b")

Этот полиморфизм сделан правильно.

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

19

К сожалению, подпись для карты, которую вы дали, неверна для карты, и есть действительно законная критика.

Первая критика заключается в том, что, подрывая подпись для карты, мы имеем нечто более общее. Это распространенная ошибка полагать, что это добродетель по умолчанию. Это не так. Функция отображения очень хорошо определена как ковариантный функтор Fx → (x → y) → Fy с соблюдением двух законов композиции и тождества. Все, что приписывается "карте", - это пародия.

Данная подпись - это нечто иное, но это не карта. То, что я подозреваю, это попытка стать специализированной и слегка измененной версией подписи "траверс" из статьи "Сущность шаблона итератора". Вот его подпись:

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

Я преобразую его в Scala:

def traverse[A, B](f: A => F[B], a: T[A])(implicit t: Traversable[T], ap: Applicative[F]): F[T[B]

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

Во-вторых, функция отображения является специальным случаем в Scala из-за ее использования в for-comprehensions. Это, к сожалению, означает, что дизайнер библиотеки, который лучше оснащен, не может игнорировать эту ошибку, не жертвуя синтаксическим сахаром понятий. Другими словами, если дизайнеры библиотеки Scala должны были уничтожить метод, то это легко игнорировать, но, пожалуйста, не на карте!

Я надеюсь, что кто-то это обсудит, потому что, поскольку это так, становится труднее обходить ошибки, которые Scala настаивает на создании, по-видимому, по причинам, к которым у меня есть серьезные возражения. То есть решение "безответственных возражений со стороны среднего программиста (т.е. Слишком сложно!)" Не "успокаивает их, чтобы облегчить им", а вместо этого предоставляет указатели и помощь, чтобы стать лучшими программистами. Задачи сами и Scala находятся в споре по этой проблеме, но вернемся к вашей точке.

Вероятно, вы делали свой прогноз, предсказывая конкретные ответы от "среднего программиста". То есть, люди, которые будут требовать "но это слишком сложно!" или некоторые такие. Это Ягеги или Блохи, о которых вы говорите. Мой ответ на эти люди в отношении антиинтеллектуализма/прагматизма довольно суровый, и я уже предвкушаю шквал ответов, поэтому я его не буду опускать.

Я действительно надеюсь, что библиотеки Scala улучшатся или, по крайней мере, ошибки могут быть безопасно спрятаны в углу. Java - это язык, на котором "попытка сделать что-нибудь полезное" настолько невероятно дорогостоящим, что его часто не стоит, потому что невозможно избежать огромного количества ошибок. Я умоляю Scala не идти по тому же пути.

  • 3
    Привет Тони - спасибо за ваш вдумчивый вклад здесь. Я бы сделал 2 ответа на это. Во-первых, я не упомянул «среднего программиста» и не считаю, что Scala обязательно нацелена на одного. Независимо от того, тщеславен ли он от меня или нет, я считаю, что я выше среднего; однако, я все еще чувствую, что сигнатура типа устрашает! Другими словами, я все еще беспокоюсь о том, что программисты выше среднего уровня, целевой рынок Scala, могут быть изгнаны.
  • 6
    Второй момент заключается в том , что я в корне не согласен с вами о том, что Scala является: Scala прагматический язык - не теоретически чистой один. Почему еще это было разработано на вершине JVM? Это чисто прагматичное решение - оно нацелено на разработчиков "в реальном мире" - выбор, который мог потребовать компромиссов! Также обратите внимание, что Блох и Йегге далеки от обычных программистов - но это моя точка зрения. Даже очень уважаемые и интеллигентные люди могут иметь мнения о сложности и чистоте, которые отличаются от ваших. К сожалению для вас, они также очень влиятельны.
Показать ещё 3 комментария
14

Я полностью согласен с вопросом и ответом Мартина:). Даже в Java чтение javadoc с помощью дженериков намного сложнее, чем из-за дополнительного шума. Это усугубляется в Scala, где неявные параметры используются как в примере кода примера (в то время как implicits очень полезны для сбора данных).

Я не думаю, что это проблема с языком как таковым - я думаю, что это больше проблема с инструментами. И хотя я согласен с тем, что говорит Йорг W Миттаг, я думаю, глядя на scaladoc (или документацию типа в вашей среде IDE) - он должен требовать как можно меньше энергии мозга, чтобы понять, что такое метод, что он принимает и возвращает. Там не должно быть необходимости взломать немного алгебры на бумаге, чтобы получить ее:)

Конечно, для IDE нужен хороший способ показать все методы для любой переменной/выражения/типа (которые, как и в примере с Мартином, могут содержать все обобщенные данные, чтобы их можно было легко и просто заглянуть). Мне нравится идея Мартина о скрытии имплицитов по умолчанию.

Чтобы взять пример в scaladoc...

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

Если вы посмотрите на это в scaladoc, я бы хотел, чтобы общий блок [B, That] был скрыт по умолчанию, а также неявный параметр (может быть, они показывают, если вы наведите небольшой значок с помощью мыши) - как дополнительный материал, чтобы читать его, что обычно не так важно. например представьте, если бы это было похоже...

def map(f: A => B): That

приятно и ясно и понятно, что он делает. Вы можете задаться вопросом, что такое "Это", если вы нажмете или щелкните по нему, он может расширить текст [B, That], выделяя, например, "Это".

Может быть, маленькая иконка может быть использована для объявления [] и (неявного...) блока, поэтому ясно, что бит бит свернут? Его трудно использовать для этого токен, но я буду использовать a. пока...

def map.(f: A => B).: That

Таким образом, по умолчанию "шум" системы типов скрыт от основных 80% того, что нужно посмотреть - имя метода, его типы параметров и его тип возврата с хорошим простым кратким способом - с небольшими расширяемыми ссылками к деталям, если вам это очень нужно.

Большинство людей читают scaladoc, чтобы узнать, какие методы они могут вызывать по типу и какие параметры они могут передать. Мы как бы перегружаем пользователей слишком подробно, как IMHO.

Вот еще один пример...

def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

Теперь, если мы спрятали объявление generics, его легче читать

def orElse(that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

Затем, если люди наведите указатель мыши, скажем, A1, мы можем показать, что объявление A1 является A1 и lt.: A. Ковариантные и контравариантные типы в дженериках добавляют слишком много шума, которые могут быть значительно упрощены для пользователей Я думаю.

  • 5
    Но что означает «То» в качестве типа результата?
11

Я не знаю, как разбить его на вас, но у меня есть кандидат из Кембриджа, и я очень хорошо использую 2.8.

Более серьезно, я почти не проводил время с 2.7 (он не будет взаимодействовать с библиотекой Java, которую я использую) и начал использовать Scala чуть более месяца назад. У меня есть некоторый опыт работы с Haskell (немного), но я просто проигнорировал материал, о котором вы беспокоились, и искал методы, которые соответствовали моему опыту с Java (который я использую для жизни).

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

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

  • 22
    Я думаю, он хочет знать, могут ли люди без докторов наук из Кембриджа справиться со Scala 2.8.
  • 2
    Хаха: трогательно! Ну, я сказал, что scala 2.8 прост в использовании - мой вопрос был больше о том, как будет выглядеть кто-то, просматривающий API, чтобы увидеть, нравится ли ему это, предполагая, что у него нет предыдущего опыта работы с Scala.
Показать ещё 2 комментария
9

Не знаю Scala вообще, однако несколько недель назад я не мог прочитать Clojure. Теперь я могу прочитать большинство из них, но не могу написать ничего еще из самых простых примеров. Я подозреваю, что Scala ничем не отличается. Вам нужна хорошая книга или курс в зависимости от того, как вы учитесь. Просто прочитав декларацию map выше, я получил, возможно, 1/3 от нее.

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

  • 5
    Речь никогда не идет о нотации (или, скажем, 10-15% о нотации), а о концепциях. И если вы достаточно умны и не увязли в знаниях за десятилетия от различных, возможно, противоречивых моделей (как я, вероятно, есть), то, как правило, понять эти вещи не так уж сложно. Но если вы научились думать и делать что-то одно, то, по крайней мере, нужно приложить некоторые усилия, и многие отреагируют на такие изменения. Это просто человеческая психология / природа. (Интересно, как психология компьютерного программирования Вайнберга выдерживает почти 40 лет?)
  • 1
    @Randall Schultz и Jeff G: Синтаксис / запись достаточно проста для умного человека. В основном разные названия для одних и тех же понятий. Быстрое освоение нового языка - это вопрос практики. ОДНАКО, шаг от процедурного к функциональному программированию ... пугающе широк. Это действительно другой способ мышления. Я несколько месяцев баловался с Clojure и считаю его относительно «простым» приятным языком FP. Но мне все еще нужно слишком много времени, чтобы разобраться с вещами, которые были бы просты в процедурном программировании.
7

Scala имеет множество сумасшедших функций (особенно там, где неявные параметры), которые выглядят очень сложными и академичными, но предназначены для удобства использования. Наиболее полезные получают синтаксический сахар (например, [A <% B], что означает, что объект типа A имеет неявное преобразование в объект типа B) и хорошо документированное объяснение того, что они делают. Но большую часть времени, будучи клиентом этих библиотек, вы можете игнорировать неявные параметры и доверять им, чтобы они поступали правильно.

  • 0
    Да, синтаксис представления ускоряет понимание.
6

Собирает ли это людей на Scala?

Я не думаю, что это основной фактор, который повлияет на популярность Scala, потому что Scala обладает большой властью, а его синтаксис не так чужд программисту Java/С++/PHP, как Haskell, OCaml, SML, Lisps и т.д.

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

Является ли это тем, что Scala плохое имя в коммерческом мире является академической игрушкой, которую могут понять только посвященные аспиранты? Будут ли отстранены руководители и руководители программного обеспечения?

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

И, для основного рынка, первое обучение Scala - это не "глоток свежего воздуха", где вы сразу же пишете программы, например, сначала используете HTML или Python. Scala имеет тенденцию расти на вас, после того как вы узнаете все детали, с которыми один наткнется с самого начала. Однако, возможно, с самого начала я прочитал Программирование в Scala, мой опыт и мнение о кривой обучения были бы разными.

Была ли библиотека перепроектирована разумной идеей?

Конечно.

Если вы используете Scala на коммерческой основе, вы беспокоитесь об этом? Вы планируете немедленно принять 2.8 или ждать, чтобы узнать, что произойдет?

Я использую Scala в качестве начальной платформы моего нового языка. Я, вероятно, не собирался строить код в библиотеке коллекции Scala, если бы я использовал Scala коммерчески в противном случае. Я бы создал свою собственную теорию, основанную на теории категорий, так как однажды я посмотрел, я нашел подписи типа Scalaz еще более подробные и громоздкие, чем библиотека коллекции Scala. Частью этой проблемы может быть Scala способ реализации классов типов, и это небольшая причина, по которой я создаю свой собственный язык.


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

Использование сборников 2.8 Scala абстракции строителя - это звуковой принцип проектирования. Я хочу изучить два компромисса между проектами ниже.

  • ПИСЬМЕННЫЙ КОД: После написания этого раздела я прочитал комментарий Carl Smotricz, который согласуется с тем, что я ожидаю от компромисса. Джеймс Страчан и davetron5000 комментируют, что смысл этого (а это даже не то, что [B]) и механизм неявного не так легко понять интуитивно. См. Мое использование моноида в выпуске № 2 ниже, что, я думаю, гораздо более явное. Комментарий Дерека Махара о написании Scala, но как насчет чтения Scala других, которые не являются "в общих случаях".

    Одна критика, которую я прочитал о Scala, заключается в том, что ее легче написать, чем читать код, написанный другими. И я считаю, что это порой бывает по разным причинам (например, многие способы написать функцию, автоматическое закрытие, блок для DSL и т.д.), Но я не уверен, если это основной фактор. Здесь использование неявных параметров функции имеет плюсы и минусы. С положительной стороны это уменьшает многословие и автоматизирует выбор объекта-строителя. В Odersky пример преобразование из BitSet, то есть Set [Int], в Set [String] неявно. Незнакомый читатель кода может не легко узнать, что такое тип коллекции, если только они не могут хорошо рассуждать о всех потенциальных невидимых неявных конструкторах, которые могут существовать в текущей области пакета. Конечно, опытный программист и писатель кода будут знать, что BitSet ограничен Int, поэтому карта String должна конвертироваться в другой тип коллекции. Но какой тип сбора? Он явно не указан.

  • AD-HOC COLLECTION DESIGN: после написания этого раздела я прочитал комментарий Тони Морриса и понял, что делаю почти то же самое. Возможно, мое более подробное изложение станет более понятным.

    В "Боевой бит-роте с типами" Odersky and Moors представлены два варианта использования. Они являются ограничениями элементов BitSet на Int и Map для парных элементов кортежей и предоставляются в качестве причины, по которой функция общего элемента сопоставления A = > B должна иметь возможность создавать альтернативные типы сбора адресатов. Тем не менее, afaik это является недостатком с точки зрения теории категорий. Чтобы быть последовательными в теории категорий и, таким образом, избегать угловых случаев, эти типы сбора являются функторами, в которых каждый морфизм A = > B должен сопоставлять объекты в одной и той же категории функторов, List [A] = > List [B], BitSet [A] = > BitSet [B]. Например, Опция - это функтор, который можно рассматривать как набор наборов из одного (объекта) и Нет. Нет общей карты из опции None или List Nil другим функторам, которые не имеют "пустого" состояния.

    Здесь предлагается выбор дизайна компромисса. В дизайне библиотеки коллекций моего нового языка я решил сделать все функтором, а это означает, что если я реализую BitSet, он должен поддерживать все типы элементов, используя внутреннее представление небитового поля, целочисленный тип, и эта функциональность уже находится в наборе, который он наследует в Scala. А Map в моем проекте нужно отображать только его значения, и он может предоставить отдельный метод без функции для отображения его кортежей (ключ, значение). Одно из преимуществ заключается в том, что каждый функтор тогда обычно также является аппликативным и, возможно, монадой. Таким образом, все функции между типами элементов, например. A = > B = > C = > D = > ..., автоматически поднимаются до функций между поднятыми аппликативными типами, например. Список [A] = > Список [B] = > Список [C] = > Список [D] = > .... Для сопоставления от функтора к другому классу коллекции я предлагаю перегрузку карты, которая принимает моноид, например. Nil, None, 0, ", Array() и т.д. Таким образом, функция абстракции компоновщика является методом добавления моноида и предоставляется явно как необходимый входной параметр, поэтому без невидимых неявных преобразований. (Tangent: этот входной параметр также позволяет добавлять непустые моноиды, которые не могут выполнять дизайн карты Scala.) Такие преобразования - это карта и сгиб на одном и том же проходе. Кроме того, я предоставляю прослеживаемое в смысле категории" Аппликативное программирование с эффектами" Макбрайда и Паттерсона, которое также позволяет карте + сбрасывать в одном итерационном проходе из любого проходящего через любое приложение, где большинство каждого класса коллекции оба. Кроме того, государственная монада является аппликативной и, таким образом, является полностью обобщенной абстракцией строителя из любой проходящей.

    Таким образом, коллекции Scala являются "ad-hoc" в том смысле, что они не основаны на теории категорий, а теория категорий является сущностью более денотационной семантики более высокого уровня. Хотя Scala неявные строители на первый взгляд "более обобщены", чем модель-функтор + моноидный строитель + обходной → аппликативный, они не доказаны, что они соответствуют любой категории, и поэтому мы не знаем, какие правила они следуют в самом общем смысле и то, что угловые случаи будут даны, они могут не подчиняться какой-либо модели категории. Просто неверно, что добавление большего количества переменных делает что-то более общее, и это было одним из огромных преимуществ теории категорий, поскольку оно обеспечивает правила, позволяющие поддерживать общность при переходе к семантике более высокого уровня. Коллекция - это категория.

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


Кроме того, я помню неполную идею о том, что некоторые из Scala компромиссов связаны с тем, что они являются одновременно изменяемым и неизменным языком, в отличие от, например, Haskell или языка, который я разрабатываю. Это согласуется с комментарием Тони Морриса о понимании. На моем языке нет циклов и не изменяемых конструкций. Мой язык будет сидеть поверх Scala (на данный момент) и многим обязан ему, и это было бы невозможно, если Scala не имел системы общего типа и изменчивости. Это может быть неверно, потому что я думаю, что Odersky and Moors ( "Fighting Bit Rot with Types" ) неверны, заявив, что Scala является единственным языком ООП с более высокими видами, потому что я проверил (сам и через Боба Харпера) этот Стандарт ML имеет их. Также представляется, что система типа SML может быть эквивалентной гибкой (с 1980-х годов), что может быть неодобрительно воспринято, поскольку синтаксис не так похож на Java (и С++/PHP) как Scala. Во всяком случае, это не критика Scala, а попытка представить неполный анализ компромиссов, на что я надеюсь, что это связано с вопросом. Scala и SML не страдают от невозможности Haskell делать множественное наследование алмазов, что очень важно, и я понимаю, почему так много функций в прелюдия Haskell повторяется для разных типов.

  • 0
    Итак, ваш язык будет объектно-ориентированным?
  • 0
    Да, наследует систему типов Scala. Одно из ключевых отличий заключается в том, что trait разделен на интерфейс и миксин, где интерфейс содержит только сигнатуры методов, а не реализацию. И только интерфейс может быть указан как тип. Последствия устранены, а классы типов обрабатываются в интерфейсе SPOT. Вот черновик деталей. Сотрудники приветствуются. Некоторый код для библиотеки здесь . Это работа, извиняюсь за упоминание паровар. Просто делюсь мыслями.
5

Кажется необходимым указать здесь степень: B.A. в области политологии и B.ed in Computer Science.

К моменту:

Собирает ли это людей на Scala?

Scala сложно, поскольку его базовая парадигма программирования сложна. Функциональное программирование пугает многих людей. В PHP можно строить закрытие, но люди редко делают. Так что нет, не эта подпись, а все остальное оттеснит людей, если у них нет конкретного образования, чтобы заставить их оценить силу лежащей в основе парадигмы.

Если это образование доступно, каждый может это сделать. В прошлом году я строил шахматный компьютер с кучей школьников в SCALA! У них были свои проблемы, но в конце концов они отлично справились.

Если вы используете Scala на коммерческой основе, вы беспокоитесь об этом? Вы планируете немедленно принять 2.8 или ждать, чтобы узнать, что произойдет?

Я бы не волновался.

4

У меня тоже есть степень математики из Оксфорда! Мне потребовалось некоторое время, чтобы "получить" новые коллекции. Но мне это очень нравится сейчас. Фактически, типизация "карты" была одной из первых больших вещей, которые прослушивали меня в 2,7 (возможно, поскольку первое, что я сделал, это подкласс одного из классов коллекции).

Чтение статьи Мартина в новых коллекциях 2.8 действительно помогло объяснить использование имплицитов, но да, сама документация, безусловно, должна лучше описать роль разных типов имплицитов в сигнатурах методов основных API.

Моя главная забота - это больше: когда выйдет 2.8? Когда будут появляться отчеты об ошибках? есть команда scala, откушенная больше, чем они могут пережевывать с 2.8/пытались изменить слишком много сразу?

Я бы очень хотел, чтобы 2.8 стабилизировался для выпуска в качестве приоритета, прежде чем добавлять что-либо новое вообще, и удивляться (смотря со стороны), если можно было бы внести некоторые улучшения в способ разработки дорожной карты для scala управляется компилятором.

0

Как насчет сообщений об ошибках на сайте?

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

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

  • 0
    Но одним из основных моментов является разница между библиотекой с точки зрения пользователя и создателей. Очевидно, что создатели нуждаются во впечатляющем понимании требуемых языковых особенностей (например, типы с более высоким родом, неявный приоритет) - вопрос: «пользователи?»

Ещё вопросы

Сообщество Overcoder
Наверх
Меню