Срач, который не начался...

1,470
19
189
Вряд ли CMTV это одобрит
 
1,111
47
420
За скалу мы вроде норм такой срачик устроили. И нормально)
 

CMTV

Основатель
Администратор
1,304
4
601
Поздно. Я уже здесь. Переезжаем.
 
7,099
324
1,510
Тему забыл закрыть)
 
7,099
324
1,510
В котлине есть такие кривенькие(имхо) конструкции:
val a:SomeType?=...
То ли дело в скалке:
val a:Option[SomeType]=...
Тип описывается чуть длиннее, зато избавляет от тонн !=null
Кто что думает по этому поводу?

P.S. Это типо попытка начать срач культурную дискуссию:D
 
1,111
47
420
Раз уж тему не закрыли я тоже набросаю говна

Тезис: Котлин хрень

Аргументы:
- Котлин туп! Не могет 1 рассмотреть как double или float приходится писать 1f или 1.0
- in и out генерики. Ужас страшный. Пример
Не компилится
Kotlin:
interface EntityRenderer<in T : Entity> {

    fun render(entity: T)

    companion object {

        val renders = HashMap<Class<out Entity>, EntityRenderer<Entity>>()

        fun renderEntity(entity: Entity) {
            renders[entity.javaClass]?.render(entity)
        }

        fun <T : Entity> register(entity: Class<T>, renderer: EntityRenderer<T>) {
            renders[entity] = renderer
        }

        init {
            register(EntityPlayer::class.java, PlayerRenderer())
        }
    }
}
Компилится
Kotlin:
interface EntityRenderer<in T : Entity> {

    fun render(entity: T)

    companion object {

        val renders = HashMap<Class<out Entity>, EntityRenderer<Entity>>()

        fun renderEntity(entity: Entity) {
            renders[entity.javaClass]?.render(entity)
        }

        fun <T : Entity> register(entity: Class<T>, renderer: EntityRenderer<T>) {
            renders[entity] = renderer as EntityRenderer<Entity>
        }

        init {
            register(EntityPlayer::class.java, PlayerRenderer())
        }
    }
}
- Kotlin не могет! Можно сделать дефолтную реализацию ф-ий интерфейсов, но нельзя прикрутить к интерфейсам поля, а в Скале можно!!1
- Kotlin и when. В скале есть прекраснейший pattern matching. Kotlin попытался сделать что-то подобное. Получилось что то сильно урезанное.
- Kotlin и кортежи. В скале есть прекрасная штука называется Tupple или Кортеж. Работает она легко val (a, b, c) = (6, 8, 9) . Соответственно можно их в сигнатуры def func: (Int, Int, Int). В Kotlin есть аналог Pair, который можно использовать как val (a, b) = Pair(0, 8), но Pair это максимум два, а в Scala не ограничено)
- Kotlin и итераторы. В скале я так могу, а в Котлине нет)
Scala:
for{
    pixel <- pixels
    val r = ((pixel >> 16) & 0xFF).toByte
    val g = ((pixel >> 8) & 0xFF).toByte
    val b = (pixel & 0xFF).toByte
    val a = ((pixel >> 24) & 0xFF).toByte
    if (a > -127)
} {
    // Some manipulations...
}
- Kotlin и операторы. В скале я могу написать такое:
Scala:
def draw(mode: Int)(block: => Unit): Unit = {
    t.startDrawing(mode)
    block
    t.draw()
}
И использовать так:
Scala:
draw(GL_QUADS) {
    t.addVertex(0, 0, 0)
    t.addVertex(1, 0, 0)
    t.addVertex(1, 1, 0)
    t.addVertex(0, 1, 0)
}
А в котлине нет)

Тезис доказан
 
2,505
81
397
В котлине есть такие кривенькие(имхо) конструкции:
val a:SomeType?=...
То ли дело в скалке:
val a:Option[SomeType]=...
Тип описывается чуть длиннее, зато избавляет от тонн !=null
Кто что думает по этому поводу?

P.S. Это типо попытка начать срач культурную дискуссию:D
Да, только в котлине это заинлайнится, а в скале это доп объект.

Котлин туп! Не могет 1 рассмотреть как double или float приходится писать 1f или 1.0
Вообще-то это так и задумано.

- Kotlin не могет! Можно сделать дефолтную реализацию ф-ий интерфейсов, но нельзя прикрутить к интерфейсам поля, а в Скале можно!!1
То что в скале это можно, немного выходит из рамок ООП. Интерфейсы могут содержать только методы. И можно заюзать проперти, если что. Будет достаточно компактно.

Kotlin и when. В скале есть прекраснейший pattern matching. Kotlin попытался сделать что-то подобное. Получилось что то сильно урезанное.
Зато инлайнится.

Юзлесс. Использовать все, что больше тройки - говнокодить. Читаемость снижается в разы. Даже тройка уже некрасиво.

Kotlin и итераторы. В скале я так могу, а в Котлине нет)
То что ты смог вот так вот наговнокодить, не значит, что ты крутой.

- Kotlin и операторы. В скале я могу написать такое:
Сейчас бы фигурную скобку называть оператором.
И в котлине я могу вот так. И это абсолютно бесплатно, т.к. заинлайнится.
Kotlin:
inline fun Tessellator.draw(mode: Int = GL11.GL_QUADS, block: () -> Unit) {
    startDrawing(mode)
    block()
    draw()
}
 
1,111
47
420
Я тя обожаю)) Определил чисто для себя стандарты и радуешься жизни)
Вообще-то это так и задумано.
А я что говорю что задумано не так? Я говорю что это дико не удобно
То что в скале это можно, немного выходит из рамок ООП. Интерфейсы могут содержать только методы. И можно заюзать проперти, если что. Будет достаточно компактно.
Не знаю, не знаю... В CPP есть))
Зато инлайнится.
В скале простейшие паттерн матчинги тоже инлайнятся. Есть специальная аннотация которая делает это явным образом.
Юзлесс. Использовать все, что больше тройки - говнокодить. Читаемость снижается в разы. Даже тройка уже некрасиво.
Котлин то и в тройку не могет)) А допустим я хочу чтоб функция вернула длину, ширину и высоту
То что ты смог вот так вот наговнокодить, не значит, что ты крутой.
Где простите весит этот великолепный список всего того что нужно и что не нужно делать? Я вроде ничего плохого не сделал, то что ты не зная синтаксис, ничего не понял твои проблемы(Там все очень понятно). Вообще это я не о своей крутости а о возможностях скалы)
Сейчас бы фигурную скобку называть оператором.
Доколебался

И в котлине я могу вот так. И это абсолютно бесплатно, т.к. заинлайнится.
В скале я могу так же) Хотя наверно и не заинлайню, но думаю @hohserg1 чо нить тут сможет добавить
 
1,111
47
420
Кстати property в Kotlin не так круты как велосипеды из функций без параметров и с пробелами в названии
 
1,111
47
420
Ооо еще записи типа a or b вместо изящного a | b или вообще a shr b вместо a << b. Твой любимый аргумент: ухудшает читаемость кода!
 
2,505
81
397
Определил чисто для себя стандарты и радуешься жизни)
Абаснуй

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

Это не показатель. С++ вообще грязный язык.

А допустим я хочу чтоб функция вернула длину, ширину и высоту
Лучший способ - запилить маленький дата класс. Зато будет очень читабельно.

Где простите весит этот великолепный список всего того что нужно и что не нужно делать? Я вроде ничего плохого не сделал, то что ты не зная синтаксис, ничего не понял твои проблемы(Там все очень понятно). Вообще это я не о своей крутости а о возможностях скалы)
Это чисто опыт. Код должен читаться, как текст. Эта конструкция нечитабельна вообще.

В скале я могу так же)
Ну я от том, что ты сказал, типа в котлине так нельзя.

Ооо еще записи типа a or b вместо изящного a | b или вообще a shr b вместо a << b. Твой любимый аргумент: ухудшает читаемость кода!
Это точно плюсую. Но тут дело привычки.

Кстати property в Kotlin не так круты как велосипеды из функций без параметров и с пробелами в названии
Опять же, это очередной способ наговнокодить.
 
Последнее редактирование:
808
3
124
Чутка подброшу за Дахакой.
in и out генерики. Ужас страшный.
Не более ужас чем в жабке, просто с более адекватным синтаксисом. Out - то же самое что ? extends T, in - то же самое что ? super T. Если в скале принципиально лучше, то иди сравнивай со скалой, а не жалуйся что не можешь в жаба-дженерики (я правда тоже до сих пор страдаю от дженериков :v)

Kotlin не могет! Можно сделать дефолтную реализацию ф-ий интерфейсов, но нельзя прикрутить к интерфейсам поля, а в Скале можно!!1
Палка о двух концах. Меня тоже зачастую печалит отсутствие возможности использовать интерфейсы как полноценные трейты, но такая возможность забила бы последний гвоздь в крышку гроба бинарной совместимости: при любом изменении списка полей в интерфейсе пришлось бы рекомпилить все классы, которые этот интерфейс реализуют. Отчасти отсутствие трейтов обходится делегатами, но тоже довольно костыльно.

Kotlin и when. В скале есть прекраснейший pattern matching. Kotlin попытался сделать что-то подобное.
По-моему, котлин попытался сделать что-то более юзабельное чем си-подобный switch/case, и получилось великолепно :D Никогда не утыкался в ограничения when-конструкций, и слабо понимаю, о чем вообще ноют скалоебы.


А почему ты не стал ничего писать про совместимые с жабкой коллекции, про рантайм влезающий в мегабайт, про нулябельность с лаконичным синтаксисом и без оверхеда, про inline как оператор и плюсы вытекающие из этого решения, про нативную поддержку в идее, про скорость компиляции, про то что язык учится за неделю в конце концов?
 
7,099
324
1,510
а в Scala не ограничено
Неправда, в стандартной либе только 22 кортежа, но можно самому сделать 23+(только зачем?)

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

про скорость компиляции
scala zinc compiler

про то что язык учится за неделю в конце концов?
Чтобы писать на скале не нужно знать язык от и до
 
Последнее редактирование:
1,111
47
420
А почему ты не стал ничего писать про совместимые с жабкой коллекции
А в скале свои коллекции и знаешь они мне нравятся больше))

про рантайм влезающий в мегабайт
Хз о чем ты ибо это:
про то что язык учится за неделю в конце концов?
Не совсем правда))
про нулябельность с лаконичным синтаксисом и без оверхеда
Иногда это хорошо но порой бесит эта история в параметрах когда ты точно не знаешь что nullable а что нет, но в принципе не плохо

По-моему, котлин попытался сделать что-то более юзабельное чем си-подобный switch/case, и получилось великолепно :D Никогда не утыкался в ограничения when-конструкций, и слабо понимаю, о чем вообще ноют скалоебы.
Ну давай попробуй
Scala:
        val a = List(6, 7, 8)
        a match {
            // Если массив начинается с 6
            case 6 :: tail => tail foreach println // Выведет 7 и 8
        }
        val b: Any = 6
        b match {
            case number: Int if number % 2 == 0 => println(s"$number is even")
            case number: Int if number % 2 == 1 => println(s"$number is odd")
            case s: String => println(s"$s is string")
        }
И это только начало. С case классами (data класс в Котлине) там все много веселее

про нативную поддержку в идее
Плагин ставится за секунду

И я еще не говорил про неявные параметры и классы))
Пример:
Scala:
abstract class Monoid[A] {
  def add(x: A, y: A): A
  def unit: A
}

object ImplicitTest {
  implicit val stringMonoid: Monoid[String] = new Monoid[String] {
    def add(x: String, y: String): String = x concat y
    def unit: String = ""
  }

  implicit val intMonoid: Monoid[Int] = new Monoid[Int] {
    def add(x: Int, y: Int): Int = x + y
    def unit: Int = 0
  }

  def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
    if (xs.isEmpty) m.unit
    else m.add(xs.head, sum(xs.tail))
   
  def main(args: Array[String]): Unit = {
    println(sum(List(1, 2, 3)))       // uses IntMonoid implicitly
    println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly
  }
}
Вещь халявная так что не надо))

Так же хочу упомянуть про lazy инициализацию которая в Kotlin не особо инлайнится а в Scala это честный автоматически создающиеся геттер
 
Последнее редактирование:
808
3
124
А в скале свои коллекции и знаешь они мне нравятся больше))
Отсутствие необходимости куда-то конвертировать коллекции на интеропе с жабакодом - это плюс настолько очевидный и необходимый для проектов, которые не могут позволить себе быть завязанными на другой язык, что спорить с этим абсолютно невозможно. Если ты делаешь приложение с самого начала на скале и юзаешь скала-библиотеки, то тебе это безразлично, конечно, но мы-то тут модиками на майнкампф зарабатываем на хлеб.

> про то что язык учится за неделю в конце концов?
Не совсем правда))
Я уже понял что ты за неделю не разобрался, не аргумент, нормальные люди разобрались))0

Ну давай попробуй
(два куска говнокода)
А реальные примеры есть? Эти - куски лютого говнокода какие-то, без значимых причин так делать убил бы за такое. Первое выглядит как технический онанизм; подобное второму часто приводят в пример адепты скалы, но часто у вас в одной переменной Int и String могут быть? Бтв, второй пример почти один в один переписывается на котлин, так что ты опять подтвердил что тебе мало недели на пролистывание коротенького референса языка и немножко экспериментов с ним :p

Плагин ставится за секунду
Нативная поддержка - это не когда плагин ставится за секунду, а когда плагин делают плюс-минус те же люди, что делали основной функционал IDE, и он в целом сделан на том же уровне.

И я еще не говорил про неявные параметры и классы))
Зато я уже говорил про скорость компиляции, и упоминание тут hohserg'ом инкрементального компилятора как будто это какой-то успех - не аргумент, он есть у всех. Надеюсь сам свяжешь скалаимплиситы с ее скоростью компиляции))

Так же хочу упомянуть про lazy инициализацию которая в Kotlin не особо инлайнится
А зачем её инлайнить-то? Работает как любое другое delegated property, никаких лишних временных объектов на повторном доступе не создается. С точки зрения перформанса инлайнить в jvm-байткоде есть смысл только там, где за счет этого получается избавиться от лишнего мусора в куче, остальное jit и так заинлайнит как ему надо. Видел бенчмарк на тему перформанаса делегатов, там как раз было про ленивую инициализацию, стоимость доступа получалась +10% относительно обычной проперти. Не вижу ничего криминального, наоборот вытащить фичу из компилятора в стдлибу - это же прекрасно, нет?


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

(весело сраться за язык когда все прекрасно понимают сферы применения, плюсы и минусы языков, но из праздного интереса продолжают топить за тот язык, который они признали более подходящим для своих задач)
 
1,111
47
420
Этот спор можно продолжать бесконечно, а мне этого не хочется. Так что это конец)
 
Сверху