scala 2.9: планы по выводу типов параметров функций с аргументами по умолчанию?

Я только начинаю работать со Scala. Я использую Python для исследовательского программирования и конвертирую довольно большую (~ 4000 строк) программу Python.

Несколько комментариев:

  1. Похоже, пришло время заняться Scala, так как в версию 2.8 было добавлено много хорошего.
  2. С другой стороны... Интересно, почему у Scala нет приличного пакета ввода-вывода, и почему это не кажется приоритетом. В большинстве языков ввод-вывод считается одной из самых фундаментальных операций, и части языка обычно разрабатываются специально для того, чтобы ввод-вывод работал хорошо. Например, библиотека IO в Python кажется одной из самых старых и стабильных частей языка (по крайней мере, в ее интерфейсе). Тем не менее, в комментариях двухлетней давности говорится что-то вроде «Source.fromFile() — это массовый взлом, подождите, пока такой-то закончит новый пакет ввода-вывода» — и я не вижу движения к завершению этого. Еще хуже тот факт, что Source.fromFile().getLines() — который, взломанный или нет, является широко рекламируемым интерфейсом — был полностью сломан изменениями, внесенными в 2.9.0.1 (см. https://issues.scala-lang.org/browse/SI-4662). Очевидно, что для этого простейшего интерфейса ввода-вывода вообще не проводится регрессионное тестирование, что является плохим признаком.
  3. Стирание типов настолько ужасно, что мне действительно интересно, почему в Scala было принято решение его вставить. Да, я знаю, что в Java есть стирание типов, а Scala построена на JVM, но в результате возникает необходимость добавлять явно видимые вещи, такие как манифесты, аннотации специализации и т. д. и т. д., чтобы обойти стирание типов, просто очень плохо пахнет ... Я чувствую, что в конечном итоге дизайнеры Scala осознают всю глупость всего этого и будут вынуждены реализовать правильную общую типизацию, после чего они тогда есть много ненужного хлама, чтобы осуждать.

Мой вопрос:

Планируется ли добавление определения типа для параметров функции с аргументами по умолчанию? Становится немного неприятно писать такие вещи:

  def add_words(words:Traversable[String], ignoreCase:Boolean=true,
                stopwords:Set[String]=Set[String]()) {
    ...
  }

В этом случае просто нет необходимости в аннотациях типов для ignoreCase и стоп-слов, и они просто добавляют ненужную многословность.

Спасибо за любые комментарии от тех, кто занимается разработкой Scala.


person Urban Vagabond    schedule 23.08.2011    source источник
comment
Я не понимаю, как ребята из scala могут исправить стирание типов, потому что они не владеют виртуальной машиной.   -  person Stilgar    schedule 23.08.2011
comment
@Stilgar, они, вероятно, могли бы передавать информацию, подобную манифесту, по умолчанию (что, я думаю, делает Госу и Котлин)   -  person Paolo Falabella    schedule 23.08.2011
comment
Хотя овеществленные дженерики немного удобнее ДЛЯ РАЗРАБОТЧИКА, чем стирание, проблема, безусловно, не так серьезна, как кажется. У JVM есть очень веские причины использовать стирание типов, что делает его более привлекательной средой, чем, например, .Net CLR. Посетите эту ссылку, чтобы узнать больше.   -  person agilesteel    schedule 23.08.2011
comment
Да... веские причины в том, что они хотели быстро реализовать дженерики и заставить все работать на уровне компилятора, чтобы виртуальные машины, написанные для различных устройств, по-прежнему поддерживались. Ссылка представляет собой статью, написанную ленивым разработчиком динамического языка. Для статического языка, такого как Scala и Java, стирание типов отстой. Мы согласны с тем, что Java — самый важный язык для JVM, не так ли? Не JRuby. Я почти уверен, что дженерики будут исправлены в какой-то момент в будущем, и на самом деле Марк Рейнхольд говорил об этом несколько раз, но это займет время. Не в Java 8 точно.   -  person Stilgar    schedule 23.08.2011
comment
@Stilgar: Итак, можете ли вы на самом деле представить систему типов с овеществленными дженериками и типами более высокого порядка? Без этого стирание типа аргумента - отстой, довольно спорный вопрос, потому что на данный момент нет ничего лучше, чем его заменить.   -  person soc    schedule 23.08.2011
comment
Овеществленные дженерики @soc (стиль .NET) намного лучше подходят для такого языка, как Java, который по-прежнему является самым важным языком в JVM. Должен признать, что я недостаточно разбираюсь в типах более высокого порядка, но я знаю, что стирание типов вредит языку Java. Я также слышу жалобы от сообщества Scala в пользу овеществленных дженериков, поэтому я предполагаю, что они являются проблемой и в Scala.   -  person Stilgar    schedule 23.08.2011
comment
@Stilgar: дженерики в Scala работают намного лучше, чем дженерики в Java. Тем не менее, стирание типа раздражает в обоих языках. Но, учитывая, что Microsoft фактически убила языковую экосистему вокруг CLR введением овеществленных дженериков (даже их собственные языки, такие как F#, должны дублировать огромные объемы кода), потому что это в основном путь C# или высокий путь, я не вижу любое решение в настоящее время. Может быть, кто-то придумает систему типов, которая может кодировать соответствующие свойства, но до сих пор никто этого не представил.   -  person soc    schedule 24.08.2011
comment
Вывод: хотя овеществленные дженерики могут быть хороши для языков с примитивными системами типов (в настоящее время только C# и C++ используют эту технику), они не решают реальных проблем. Scala может жить с HKT и стиранием типов, но не может жить без HKT и материализованных дженериков. Так что, если у вас есть решение, я был бы рад услышать его. Простое добавление уточненных дженериков не работает.   -  person soc    schedule 24.08.2011


Ответы (3)


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

    Возьмем, к примеру, вашу проблему со стиранием. Как пользователь версии 2.0 у вас будет больше шансов что-то сделать, чем сейчас. На самом деле влияние, которое могло бы быть на совместимость, в значительной степени является гарантией того, что этого больше не произойдет, если только Java не станет лидером.

  2. Вы пришли из языка сценариев. Языки сценариев очень сильно связаны с вводом-выводом, потому что это их масло и хлеб. Для Scala любой серьезный ввод-вывод просто переносится в библиотеки Java — в конце концов, в этом и заключается смысл совместимости Scala с Java.

    Кроме того, ваша характеристика 4662 на самом деле совершенно неверна. Он не был совсем сломан, хотя изменение поведения заставило, возможно, неверный код снова работать. Вкратце это 4662:

    val source = scala.io.Source.fromFile(new java.io.File("test1.file"))
    use(source)
    val lines = source.getLines
    

    Поскольку source — это Iterator, оно исчезнет, ​​как только вы его используете. То, что вы могли повторно использовать его после вызова toString, было совпадением, а не внутренней гарантией.

  3. Стирание шрифта не так уж и плохо. На самом деле, это признак плохого дизайна, если он сильно мешает — вы не должны проверять тип чего-либо, а должны вызывать методы для этого и позволять этому обрабатывать себя. . Не сказать, что временами это не раздражает, но не так сильно. Увы, это фундаментальный выбор в плане полной совместимости с Java, и он был сделан очень сознательно. Я не вижу, чтобы Scala лидировала в этом.

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

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

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

person Daniel C. Sobral    schedule 24.08.2011
comment
Привет, извините за поздний ответ. Я действительно удивлен, что вы думаете, что единственная проблема стирания шрифта заключается в том, что вы не можете проверить тип чего-либо. Стирание типа, по крайней мере, в Java, означает, что если у вас есть, например. a List[T], вы даже не можете создать новый объект T! А проверка типа — это на самом деле обычная идиома Scala с match. Посмотрите на Hadoop API — вам нужны эти уродливые вызовы setFooClass(), setBarClass(), setBazClass() повсюду именно для того, чтобы обойти тот факт, что вы не можете создать новый T с учетом Foo[T]. - person Urban Vagabond; 04.09.2011
comment
@Urban Я не думаю, что создание экземпляра T - хорошая идея для начала. Фабрики - правильный способ сделать это, и вы можете передавать фабрики друг другу. На самом деле, даже Manifest — своего рода фабрика. - person Daniel C. Sobral; 04.09.2011
comment
Почему нет? Фабрики - единственный правильный способ сделать это, потому что стирание шрифта заставляет вас это делать. Кроме того, как я уже сказал, использование «match» является одним из общепринятых идиом Scala. В книге Scala2e приводится множество аргументов, почему это не всегда лучший способ реализовать все с помощью методов, определенных в классах. - person Urban Vagabond; 04.09.2011
comment
@Urban Проще говоря, это нарушает первую часть принципов SOLID. Вы можете посмотреть принципы SOLID, и вы найдете много информации. - person Daniel C. Sobral; 05.09.2011

  1. да

  2. Поскольку базовая виртуальная машина абстрагирует любой доступ к внешнему миру, в основном существует возможность либо поставляться с скомпилированным кодом, что делает Scala не независимым от платформы, либо использовать такие вещи, как java.io.File, которые просто полностью сломаны. В Java 7 (спустя всего 15 лет) наконец-то добавлен некоторый пригодный для использования API файловой системы, который, насколько я знаю, уже нацелен на разрабатываемую библиотеку ввода-вывода Scala. Еще один момент — поддержка других платформ времени выполнения. Не рекомендуется выпускать библиотеку Scala IO, которая имеет только реализацию JVM. Итак, в основном: наличие приличной библиотеки ввода-вывода стало возможным благодаря Java 7 несколько недель назад. Учитывая, что Scala не прекратит поддержку Java 6 (и 5) в ближайшем будущем, не ожидайте, что в ближайшее время IO будет поставляться со стандартной библиотекой.

  3. Вы используете его неправильно. Но не стесняйтесь создавать свой собственный язык, который делает все лучше, если вы думаете, что «разработчики Scala поймут глупость». Овеществленные дженерики трудно комбинировать с типами более высокого порядка. И если бы мне пришлось выбирать, я бы каждый раз выбирал HKT вместо материализованных дженериков.

Аааа.. верно. Это не ваши вопросы. Ответ на ваш актуальный вопрос:

Это можно сделать, но людям нравится соблюдать простые правила. Так что, вероятно, нет.

person soc    schedule 23.08.2011
comment
Вы говорите, что вы используете это неправильно. Но не стесняйтесь создавать свой собственный язык, который делает все лучше, если вы думаете, что разработчики Scala поймут, что глупость не очень дружелюбна. Это был правильный вопрос, и, вероятно, в умах большинства людей, имеющих опыт работы со сценариями. - person Salil; 24.08.2011
comment
Салил: Я не хотел показаться резким. Учитывая, что почти все языки сценариев нетипизированы, я не понимаю ваше последнее предложение. Хотите уточнить? - person soc; 24.08.2011
comment
большинство людей, которые плохо знакомы с миром Java, будь то сценарии или C++/C#, не ценят «стирание типа». Это приводит к особым случаям при проверке типов, а также в операторах case Scala. Сами манифесты — это способ обойти ограничения стирания типов. «Городской бродяга» поднял обоснованный вопрос о том, почему Scala решила продолжить ту же «ошибку», что и Java. Ваш ответ типа «иди, создай свой собственный язык» прозвучал слишком резко. - person Salil; 24.08.2011
comment
Думаю, мы в значительной степени согласны. Я думаю, что все поняли негативные аспекты стирания шрифта. Но это просто не решение, чтобы просто исправить это, не упоминая, как это сделать. Вот почему я действительно хотел бы увидеть работающее решение, а не указывать на очевидное. - person soc; 24.08.2011
comment
Вы действительно не должны отвечать краткими комментариями на StackOverflow, держите их при себе или заявляйте о своем превосходстве над n00bs на scala-user. - person ThaDon; 25.09.2011

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

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

проект = СИ И (сводка ~ "по умолчанию" И сводка ~ "значение")

  1. нет комментариев
  2. нет комментариев
  3. Как указывали другие, овеществление (т. е. не стирание типа) усложняет реализацию дженериков более высокого типа. Вот прямая цитата из раздела 6.1 "Генериков высшего рода", Писсенса, Мавра, Одерского.

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

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

Вы можете просмотреть эту статью для объяснения того, почему дженерики более высокого типа важны. Хотя Scala 2.8, по-видимому, не использует их широко в своей новой библиотеке коллекций, до сих пор Я обнаружил, что невозможно реализовать мою библиотеку теории категорий элегантным образом с подтипами без высших видов (сравните это со Scalaz дизайн без подтипов, который я считаю чрезвычайно сложным).

Дэниел С. Собрал относительно вашего комментария под вашим ответом, я думаю, что конструкторы нарушают принцип D в SOLID. Городской Бродяга, фабрики должны использоваться для достижения инверсии управления, a/k/a голливудский принцип. См. также блог Гилада Брахи «Конструкторы, признанные вредными».

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

person Shelby Moore III    schedule 25.09.2011