1. Куча / Говнокод #16093

    +96

    1. 1
    2. 2
    var m = map[int]string { 1: "one", 2: "two", 3: "three", }
    if val, ok := m[3]; ok { fmt.Printf("Yes! %s\n",val) }	else { fmt.Println("No!") }

    Почему в Go первое присваивание надо писать через =
    А то что в if через :=
    http://ideone.com/cPf2cw
    http://ideone.com/fork/cPf2cw

    Запостил: 3.14159265, 01 Июня 2014

    Комментарии (41) RSS

    • Какой-то поцкаль, только шиворот-навыворот получается.
      Сначала показалось - владельцы селеронов 600 будут довольны - в языке нет исключений, присваивание :=, типа быстрая компиляция.
      Но потом оказывается - вместо исключений panic, equals ==, gc, да и сишкобляством несёт за версту, хоть и старались пофиксить.
      Не. Тарасу явно не понравится.
      Ответить
      • да нахуй воскрешать мертвые идеи из трупных языков.

        хотя. дело смоллтолка живет
        Ответить
        • >да нахуй воскрешать мертвые идеи из трупных языков
          Потому что практически всё новое - это хорошо забытое старое.
          Ответить
    • потому что = пишет в существующие переменные, а := создаёт новые.
      var m = эквивалентно m :=
      Ответить
      • Гы, оригинально.
        Ответить
      • >потому что = пишет в существующие переменные, а := создаёт новые.
        Я прочитал мануал.
        >var m = эквивалентно m :=
        Но вот этого не понял. Зачем два разных значка для объявления переменной? Сахарок, в языке, в котором по идее подобные излишества должны быть выкорчеваны на стадии проектирования.
        При том что сравнение сделали обратно через уродское ==.
        we believe Go's type syntax is easier to understand than C's, especially when things get complicated.
        Ответить
        • Видимо, решили, что объявление с инициализацией достаточно частый кейс, чтобы завести под него отдельный синтаксис. И/или хотелось немножко походить на скриптовые языки, в которых объявлений переменных нет.
          На самом деле var используется только для неинициализированных переменных или при желании явно указать тип.
          Ответить
          • >var используется только [...] при желании явно указать тип.
            a string:=""
            var a string =""
            Ответить
            • Т.е. сначала имя, а потом тип?
              Ответить
              • Да. По-человечески сделали. a типа строк.
                Ответить
                • > По-человечески сделали.
                  А по мне - так фигня какая-то:
                  - иногда - лишнее слово var, которое потом надо читать
                  - с виду - присваивание значения типу: var a string =""

                  Да и "психологическая" модель чтения кажется мне неуместной:
                  "Здравствуйте, я - Вася, программист на крестах" - важен Вася и его психическое состояние,
                  "Программист Вася написал за неделю три новых класса" - важен программист и его результаты.
                  Маша, я - строка" - ну, привет, Маша, зачем ты здесь вообще?
                  "Запишем логин в строку Машу" - реализация алгоритма.
                  Сигнатуры - по типу, хугление - по типу, потребность в документации очевидного в жс - из-за отсутствия типов. Хоть ты и личность, Маша, но всё же ты - строка.
                  Ответить
                  • > иногда - лишнее слово var, которое потом надо читать
                    > с виду - присваивание значения типу: var a string =""
                    Оно не лишнее. string можно не писать, он выведется автоматом.
                    var a="" //это уже как в привычном и любимом js

                    >Да и "психологическая" модель чтения кажется мне неуместной:
                    Это просто сишкоблядство прочно уселось в мозг.

                    > с виду - присваивание значения типу: var a string =""
                    Да это практически паскальное var i:Integer;
                    или бейсиковское Dim i as Integer
                    Только с автовыводом, возможности инициализации присваиванием и удалением : и as между переменной и типом.
                    Ответить
                    • > var a="" //это уже как в привычном и любимом js
                      Это уже "переменная a", порядок как в сишке, хотя по логике языка надо бы a:var := ""

                      > сишкоблядство прочно уселось в мозг
                      > это практически паскальное
                      сишкоблядство прочно уселось в мозг, паскальный синтаксис воспринимается как справка от врача.
                      Ответить
                  • Сразу видно человека, не ведающего, почему в плюсы добавили волшебное слово typename и заставляют бедных программистов рисовать непонятные стрелочки.

                    Указание типа ПЕРЕД именем переменной создаёт неоднозначность и приводит к унылым костылям. Поэтому практически все современные языки использую нотацию var name: Type.

                    Примеры:
                    template <typename T>
                    void doIt()
                    {
                        T::my_type *x; // умножаем константу в классе
                        // на некий глобальный x
                        // или объявляем переменную?
                        // x: Ptr[T::MyType]; - не перепутаешь
                    }
                    
                    // да здравствуют костыли и новый синтаксис
                    // ради тривиальных вещей
                    template <typename T>
                    auto add(T x, T y) -> decltype(x + y);
                    
                    // Было бы гораздо лучше
                    // template <typename T>
                    // fn add(x, y : T) : decltype(x + y);
                    Ответить
                    • typename не надо писать на каждом шагу, не так страшно.
                      А человек - не парсер, человек хочет писать код и в идеале плевать он хотел на грамматику языка и проблемы компилятора.

                      Как я понял из Ваших примеров, если добавить новую сущность (:), возникающую только при описании новой переменной, неоднозначность уходит, и можно жить.
                      T::my_type*: x; // тот же порядок, вместо typename и паскалепорядка
                      auto decltype(x + y): add(T x, T y);
                      Ответить
                      • > typename не надо писать на каждом шагу
                        Ты, очевидно, мало шаблонного кода видел :)

                        > и в идеале плевать он хотел на грамматику языка и проблемы компилятора

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

                        > decltype(x + y): add(T x, T y);

                        Нельзя, потому и ввели дурацкую стрелку. Нужно знать, что такое "x" и "y" до того, как их увидишь в выражении.

                        Опять же, тип перед переменной вынуждает всегда писать либо сам тип, либо плэйсхолдер. С учётом того, что тип зачастую ясен и без явного его указания, паскалевский синтаксис более предпочтителен, т.к. позволяет опускать этот самый тип, используя его лишь как уточнение в случае необходимости. Scala:
                        var x = 5
                        var x: Long = 5
                        val y = 15
                        val y: Long = 15
                        Ответить
                        • > Нужно знать, что такое "x" и "y" до того, как их увидишь в выражении.
                          Ну дык Вирт же компилер и парсер делал, чтоб по LL(1) разбирать.
                          Ответить
                          • > Ну дык Вирт же компилер и парсер делал, чтоб по LL(1) разбирать.

                            я знаю, но для 1024-- это врядли будет аргументом :)
                            Ответить
                            • >я знаю, но для 1024-- это врядли будет аргументом :)
                              Ну по всей видимости да :)
                              >>паскальный синтаксис воспринимается как справка от врача.
                              Ответить
                            • > для 1024-- это врядли будет аргументом :)
                              Если время парсинга исходников на практике сопоставимо (или больше) со временем компиляции, аргумент.
                              Ответить
                        • > У человека в точности такие же проблемы с парсингом, как и у компилятора.
                          Но у человека есть ещё комментарии, отступы по горизонтали и вертикали. А запутать в любом стиле можно
                          type1 : int;
                          a : type2;
                          b ; type1;


                          > паскалевский синтаксис более предпочтителен, т.к. позволяет опускать этот самый тип, используя его лишь как уточнение в случае необходимости
                          В C# смогли и типы, и var сделать без паскалевского синтаксиса.
                          Ответить
                          • > В C# смогли и типы, и var сделать без паскалевского синтаксиса.

                            Я разве говорил, что это не реализуемо? Ты что-то путаешь.

                            > тип перед переменной вынуждает всегда писать либо сам тип (List<Lols>), либо плэйсхолдер (var)

                            Теперь посмотри, насколько убого сишарпные const, var и readonly смотрятся по сравнению со Scala.
                            Ответить
                            • > Я разве говорил, что это не реализуемо?
                              >> паскалевский синтаксис более предпочтителен
                              Меня это зацепило. Как все уже слышали, мне нравится сишный порядок, и для меня нет смысла предпочитать что-то другое.

                              Про проблему массивов указателей я пока молчу, меня бы устроило что-то смешанное вида const & const[const * const int] - константная ссылка на константный массив константных указателей на константный int.

                              const[const int (int, int)] - легко распространяется на указатели на функции
                              const[const int (Type; int, int)] и функции-члены
                              Ответить
                              • > меня бы устроило что-то смешанное вида const & const[const * const int]

                                Здесь тоже всё просто решается - специальный синтаксис не нужен совсем. Нужно иметь встроенные параметризованные типы Ptr[T], Array[T], etc.
                                Ответить
                      • Как человек большую часть рабочего времен пишуший на ж.скрипте с типами (либо Хексе, либо АС). Даже при моей искренней нелюбви к Фортрано-подобным, пистать тип после имени переменной при объявлении лучше по следующей причине:
                        тип, если он опциональный, хочется иногда опустить. Гораздо легче понять что тип, а что имя переменной если можно опустить только последнее слово в объявлении.
                        С порядком следования слов в русском языке сравнивать бесполезно по ряду причин:
                        - порядок следования слов в есстесственных языках такой не потому, что кто-то так задумал, проверил, что так лучше, и решил использовать. Порядок получился случайно, и как показывает практика других языков, у человека нет каких либо предпочтений к тому, где именно должно быть подлежащее, сказуемое и другие части предложения. Есть определенные правила, типа управление, анафора, фронтинг и т.д. которые предотвращают определенные "невозможные" порядки следования, тем не менее, эквивалентных вариантов тьма.
                        - люди не читают программы как прозу. Бессмысленно пытаться сделать програмы похожими на нее. Даже если добиться большой похожести, это не сделает програму понятнее, в большинстве случае - скорее наоборот. Эти два вида изложения преследуют разные цели: минимум разночтений для формальных языков и комбинацию фонетически приятных сочетаний с соответствием литературной традиции.
                        Ответить
                  • > Да и "психологическая" модель чтения кажется мне неуместной:
                    > "я Маша, я - строка" - ну, привет, Маша, зачем ты здесь вообще?
                    "Запишем логин в строку Машу" - реализация алгоритма.

                    В английском порядок слов обратный.

                    My name is Masha. I'm a string.
                    Write a login to the masha variable of type string.

                    Более того, имена обычно не произвольные "маша". Они что-то означают. Причём их имя задаёт интерпретацию, оно обычно важнее их типа.
                    Что важнее - то, что в переменной login "хранится" логин пользователя, или то, что логин по случайности представлен строковым типом? Тип - это делаталь реализации, имя - часть ментальной модели.
                    Ответить
              • отпал кусок коммента при редактировании.
                var a string - переменная a типа строка.
                const b int32 - константа b типа целое
                Ответить
          • >Видимо, решили, что объявление с инициализацией достаточно частый кейс,
            Да по-моему они просто хотели угодить поцкалистам-делфятникам, возможно зная что многих сызмальства обучали(ют) именно на них.
            Отсюда и странный способ записи массива
            intArray  : Array[10] of Integer => intArray [20] int //осишкованое и упрощенное объявление массива
            
            for i := 0 to 10 do               => for i := 0; i < 10; i++  //не правда ли похоже, только сишно
            (for var i=0; i < 10; i++ )  //этот вариант для жаваскриптеров и остальных
            
            function len(k: string): integer; =>  func len (k string) int
            Ответить
      • А вот еще массивы. Почему тип объявляется так
        var a []int
        а обращение к элементам идёт по старинке: a[1]
        В чем глубинная простата? Как это логически соотносится с самым сумасшедшим объявлением мапов, что я видел:
        MapType = "map" "[" KeyType "]" ElementType .
        Таки крестошаблоны и прочие женерики почитабельнее будут.
        Ответить
        • >глубинная простата
          Это до которой пальцем не дотянешься?
          Ответить
        • > Таки крестошаблоны и прочие женерики почитабельнее будут.

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

          map[string]map[string][]*int
          Ответить
          • а что, контейнеров с тремя шаблонными параметрами нет?
            чтобы отличить третий шаблонный параметр от продолжения второго
            Ответить
            • Шаблонов вообще нет, см коммент ниже.
              из вколоченных в компилятор шаблоных типов: хэштабличка map[K]V, слайс []T и канал chan T.
              Ответить
          • >На самом деле это дело привычки. Кмк гошные декларации типов очень удобны, если к ним привыкнуть.
            Ну я вчера думал над этим.
            С мапой есть своя логика, m map [string] int в квадратных скобках означает что вспоследствии в m[] квадратных скобках появится строка. Но вот скобки в массиве-то нахрена менять местами ?
            Ответить
            • > Но вот скобки в массиве-то нахрена менять местами ?
              >> По сути мы пишем в точности то, что говорим

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

              []int - массив целых
              []*int - массив указателей на целое

              int[] - массив целых? ok.
              *int[] - указатель на массив целых? или массив указателей на целое?
              Ответить
              • ... m[5]*int ... - массив указателей с именем m или элемент мапы умноженный на int чёто-то там?
                Ответить
    • На самом деле синтаксис быстро осваивается и даже через некоторое время начинает нравится. Проблемы у Го совсем на другом уровне:

      1. Отсутствие динамической линковки, мегабайты бинарников.
      2. Нет дженериков (кроме встроенных). Меня это очень печалит. Отсюда следующий пункт
      3. Приходится писать много бойлерплейта для типичных структур данных и алгоритмов. Это очень уныло.
      4. Код, использующий гошные интерфейсы, ощутимо сливают по производительности коду, не использующему интерфейсов.
      Ответить
      • >На самом деле синтаксис быстро осваивается и даже через некоторое время начинает нравится.
        За пару дней освоил. Помесь сишки, жабы и возможно ерланга (стрелочки), только с выпилом тонн ненужного синтаксиса.
        > Нет дженериков (кроме встроенных).
        Это наверное самое отстойное. Даже в сишке новой какие-то препроцессорные делают.
        Ответить
      • >даже через некоторое время начинает нравится
        Понятно что на говнокоде это не нужно. Но из того что понравилось. Сделали как надо - поменяли обратно местами тип и переменную, очень интересное наследование, типы мечты: int8,int16, float32, нормальный свич, интересная концепция туплов и связанная с ней обработка ошибок (сразу подумал что Тарасу такое оценит), из жабы взяли только самое необходимое пакеты, импорты, интерфейсы - кучу жавовских и крестоблядскийх ключевых слов (private,protected,public) оставили.

        Из того что спорно, или я пока не въехал
        Убрали из бинарного отрицания тильду ~ и сделали ^, логика определенная в этом есть, но не совсем понятно нахрена - теперь сложнее байтоебские коды портировать. А еще мне ^ никогда не нравился как xor.
        finally вернее defer какой-то странный
        Ответить
    • Сколько языков хороших погибла из-за того что за ними не стоял гугл или любая другая объёмная компания.
      Ответить

    Добавить комментарий