Pull to refresh

Comments 42

Запечатанный класс нельзя применять за пределами текущей единицы компиляции (compilation unit).
В оригинале:
A sealed type in Scala is not extensible outside of the current compilation unit.
.
Не «применять», а «расширять» (наследовать). Если бы sealed классы нельзя было применять вне файла, в котором они объявлены, то в них было бы мало смысла.
def whoLetTheDucksOut(d: {def quack(): String}) {
 println(d.quack());
}

Неслучайно в качестве примера был выбран quack() — структурная типизация имеет много общего с «утиной типизацией» в том же Python. Однако в Scala типизация осуществляется при компиляции, что говорит о гибкости языка с точки зрения выражения типов, которые было бы трудно или невозможно выразить в Java. К сожалению, здесь система типов имеет очень небольшие возможности по структурной типизации. Можно задать локальный анонимный тип с дополнительными методами, и если один из них будет сразу же вызван, то Java позволит скомпилировать код.

В данном примере используются structural types, которые реализуются через reflection. Так что проверки компилятором нет.

Проверка компилятором как раз есть.
scala> whoLetTheDucksOut(new { def quack() = "quack!" })
quack!

scala> whoLetTheDucksOut(new { })
<console>:13: error: type mismatch;
 found   : java.lang.AnyRef
 required: java.lang.AnyRef{def quack(): String}
       whoLetTheDucksOut(new { })
                         ^

Но есть и рефлексия. Из-за нее проседает производительность, но и эту проблему, возможно, пофиксят. По крайней мере есть пути решения.
UFO just landed and posted this here
А в чем огромная польза, на ваш взгляд?
UFO just landed and posted this here
оооо, как богато.

рефлекшен и оверлоадинг методов не стыкуются, надо каждый раз указывать все аргументы, чтоб найти метод — это неудобно

а как бы вы сделали?

Представьте себе аналог jdbc, который вам отдаёт итератор над по-человечески типированными кортежами

а как типы данных определяются? Контежи типизированные? Чем вам Spring-JDBC не нравится?

ораклу стоило бы больше внимания уделать эффективной работе новых языков на JVM

вы можете поизучать эту тему на досуге и попытаться понять, что, во-первых, оракл этим уже занимается, а во-вторых, это сущая благотворительность, потому что доля этих самых «новых языков на JVM» меньше, чем погрешность изменения, которым она считается.

Разрабы утверждают

разрабы могут утвеждать всё, что угодно. Только вот цейлона в TIOBE нет даже в Top-50. (там доля в 0.2% является достаточной для попадания, если что).
UFO just landed and posted this here
слушайте, я вам задал вполне конкретные вопросы, а вы мне в ответ философию какую-то.

Давайте я совсем просто переформулирую:
1. Как сделать рефлекшен по куче перегруженных методов?
2. как типизировать кортежи (ruple, row), прилетающие из БД?
3. зачем вендору вкладываться в развитие языков, на которые никто не пишет?
4. как можно сравнивать «клевый» язык, которым мало кто пользуется с языком, которым пользуются десятки миллионов людей?
5. насчет языков и хабраопроса — вы знаете, что такое «survivor bias»?
UFO just landed and posted this here
Хотел у вас спросить, несколько отклоняясь от основной линии дискуссии. Я уже не первый раз вижу негативное отношение к перегруженным методам с scala-сообществе. И, если я правильно понимаю, вы разделяете это мнение. Но я никак не могу понять, чем можно было бы их заменить, и в чем конкретно проблемы с ними связанные, кроме более сложного рефлекшена. Просто, только лишь усложнение рефлекшна мне кажется гораздо менее важным, чем наличие перегрузок, т.к. рефлекшн, по большому счету некий костыль, которым пытаются компенсировать негибкость языка и его использование в любом случае должно быть минимальным.
UFO just landed and posted this here
UFO just landed and posted this here
Паттерн матчинг, возможность дважды наследовать интерфейсы с разным параметром типов, перегрузка методов.

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

Java-программистов, понятное дело, это не напрягает. Они вместо сложных отношений типов фигачат везде Object и приводят его по мере необходимости. Концепция статических типов и типобезопасного программирования прошла мимо них.
UFO just landed and posted this here
В течение многих лет большинству хватало (да и сейчас, поверьте, многим хватает) if, else и goto :)
if, else

… которые, в сущности, выражаются через goto, так что список можно сократить до одного элемента :)
Тормоза бы лучше починили, все остальное терпимо
Мне кажется, или я вижу вас в каждом треде про JVM-based langs и вы везде говорите, что они тормозят?
Ну я же правду говорю :) К сожалению приходится пользоваться тулами, написанными на JVM-based langs и их производительность меня категорически не устраивает.
Мыши кололись, но ели кактус. (с) Если вам придется пользоваться кривонаписанной криворукими разработчиками программой на C, вы будете в каждой статье тогда язык С обвинять? Найдите аналогичные тулы, которые не написаны на JVM, смените работу в конце концов, зачем же так мучится и тратить нервы.
Не для всего есть альтернатива.

>Если вам придется пользоваться кривонаписанной криворукими разработчиками программой на C
Это вы сейчас про JVM?
Вам уже говорили, что дело не в JVM, а в ваших утилитах, кривые руки они хоть на асемблере — кривые руки. Ниже я написал про конвертеры в нативный код, попробуйте может поможет.
Кстати, попробуйте тут описаны тулзы по конвертации jar файлов в нативный код: такие как Launch4j и packr. Если я понял ваша главная проблема загрузка JVM, попробуйте перегнать все в натив и может быть вам будет счастье.
Если он решит проблему — он больше не сможет ныть.
Натив? Он же просто пакует выбранную JVM в бандл
Например, в описании packr указано что он перегоняет в найтив и jar и jre, при этом есть возможность ограничить только нужной частью jre. И что он наиболее подходит для GUI приложений. Не знаю, не пользовался, но описание на github'e выглядит интересно.
Уж хотя бы свойства могли бы добавить. Но видимо не несущий функциональности, синтаксический сахар считается раздувающим язык и затрудняющим понимание.
Автор, что Вы можете сказать о Kotlin?
Лично мне не хватает typedef'ов для повышения читабельности параметризованных типов — страдаешь сначала записывая объявление, а потом еще и читая его
Например, в С++ лямбда-выражения появились только в 14 версии
Лямбды появились в С++11
Более выразительный синтаксис импорта

не помню когда в последний раз писал импорт руками
Я пишу на Java и на Ruby, после Ruby больше всего не хватает именованных (непозиционных) аргументов и значений аргументов по умолчанию.
def foo(arg1:, arg2: nil)

end

Куда больше не хватает unsigned Integers, но эта тема в статье раскрыта.
Литералов регулярных выражений не хватает. Экранирование регулярного выражения выраженного строкой распухает сильнее, чем могло бы, будь отдельный литерал для регэкспов.
Вот чего мне реально не хватает:
К примеру переделать сравнение примитивных типов Integer == int, чтобы не падало NPE, А выдавало false если null сравнивают с 666 к примеру.
Ещё чтобы == работал для String, а не надо было писать «bla».equals(«bla»)
Давайте разделим фичи на три типа:
1. тяжелые, значительно затрагивающие работу VM
2. средние, добавляющие в язык определенный функционал, но контролируемых на уровне компилятора
3. легкие — всякий синтаксический сахар

К первому типу будет относиться value types, если когда-нибудь вообще выйдут. За все время существования Java не было сделано столь серьезных изменений. Даже появление generics и лямбд фактически не затрагивало VM. Любую подобную фичу реализовать с гарантией обратной совместимости будет огромной проблемой. Придется решать сразу огромный круг задач из всевозможных областей, менять спецификации, JMM, валидатор кода, поддерживать на всех архитектурах, etc…

Второй тип — это все, что до сих пор делалось в Java. Тем не менее всегда проблемно что-то встроить, не поломав совместимости. С одной стороны у нас есть крутая фича, с другой — API Java и куча легаси-кода, который нужно мигрировать. Основной затык в лямбдах был именно встроить их в коллекции. Разработчики реально задолбались, в итоге выкинули все нахрен и сделали отдельно Stream. Даже такая простая вещь как unsigned тип поломает все и сразу: сериализацию, все библиотеки, работающие с рефлекшном, абсолютно все фреймворки, etc…

Сахар? Ну а как бы зачем? Семантически запись не меняется, лишь делается чуть короче, что не имеет большого смысла, т.к. сегодня IDE берет на себя всю нагрузку по печатанию кода. Посмотрите, какая полемика развернулась по поводу var. Так что импорты, литералы и прочее — это то, что меньше всего волнует.

Поэтому если вам нужна гибкость и плюхи, и вас не беспокоит, то, что через год-два ваш код не будет компилироваться или работать — всегда есть альтернативные JVM языки.
Мне, как C# программисту, но которому приходится программировать и на java (android) самым главным минусом является отсутствие делегатов, и, как следствие, нормальных событий.
Написание интерфейсов OnXXXListener на каждый чих весьма утомляет. Делегаты делают все гибче и проще.

Не хватает и свойств, геттеры-сеттеры функции не так удобны и красивы. Но это чисто сахар.

Так же не хватает неких аналогов async, но C# они реализуются на уровне компилятора через корутины, которых тоже нет (?).
UFO just landed and posted this here
Я так и делаю, что я и написал. Но это менее удобно и более утомительно.
Мне, например, не хватает Case classes, как в Scala.
Sign up to leave a comment.