Состояние


Мы вовсю работаем над Go 1.13, релиз которого, надеюсь, состоится в начале августа этого года. Это первый релиз, который будет включать в себя изменения конкретно в языке (а не просто незначительные правки спецификации) после длительного моратория на любые такие изменения.


Чтобы прийти к этим изменениям в языке, мы начали с нескольких жизнеспособных предложений (proposals), отобранных из гораздо большего списка предложений по Go 2, в соответствии с новым процессом оценки предложений, описанным в посте "Go 2, here we come!". Мы хотели, чтобы первичный отбор предложений нами играл относительно малую роль и, по большей части, не вызывал споров, чтобы с большой вероятностью они бы прошли весь этот процесс. Предложенные изменения должны были быть обратно совместимыми, чтобы сломать как можно меньше, поскольку модули (которые в будущем позволят выбрать версию языка для конкретного модуля) пока еще не являются режимом сборки по умолчанию. Коротко, текущий начальный этап изменений был больше направлен на то, чтобы снова сдвинуться с мертвой точки и получить опыт, а не на решение больших проблем.


Наш изначальный список предложенийUnicode в общем виде в идентификаторах, двоичные целочисленные литералы, разделители для числовых литералов, битовые сдвиги на знаковое целое — был и укорочен, и расширен. Предложение по Unicode в общем виде в идентификаторах не пережило сокращения, поскольку мы не успели вовремя составить дизайн-документ. Предложение по двоичным целочисленным литералам было значительно расширено и привело к всестороннему пересмотру и модернизации синтаксиса числовых литералов Go. Также мы добавили черновой вариант предложения Go 2 по проверке ошибок, который был частично принят.


С учетом этих начальных изменений в Go 1.13, пришло время задуматься о будущем Go 1.14 и определить, что мы хотим изменить далее.


Предложения по Go 1.14


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


С улучшением системы модулей Go решается проблема управления пакетами и версиями. Остаются улучшение обработки ошибок и дженерики. Мы работали над обеими проблемами и представили черновики дизайн-документов на прошлогоднем GopherCon в Денвере. С тех пор мы постепенно улучшали их. По обработке ошибок мы опубликовали значительно переработанное и упрощенное предложение (см. ниже). Что касается дженериков, то мы работаем над этим, на эту тему на GopherCon в Сан-Диего в этом году состоится выступление Иэна Лэнса Тейлора "Generics in Go", однако мы пока не дошли до этапа, когда могли бы предоставить конкретное предложение.


Мы также хотим продолжить понемногу улучшать сам язык. Для Go 1.14 мы выбрали следующие предложения:


#32437. Встроенная функция проверки на ошибку — "try" (дизайн-документ).


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


#6977. Разрешить встраивание перекрывающихся интерфейсов (дизайн-документ).


Это старое обратно совместимое предложение для того, чтобы сделать встраивание (embedding) интерфейсов более толерантным.


#32479. Предупреждать о преобразовании вида string(int) в go vet.


Преобразование вида string(int) давно было добавлено в Go для удобства, однако оно очень путает новичков (string(10) — это "\n", а не "10") и более не оправдано, поскольку сейчас преобразование доступно в пакете unicode/utf8. Поскольку удаление этого преобразования не является обратно-совместимым изменением, мы предлагаем вместо этого выдавать ошибку при выполнении go vet.


#32466. Принять принципы проектирования по криптографии (дизайн-документ).


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


Следующие шаги


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


Если эти предложения не встретят явных проблем, то мы планируем все реализовать в начале цикла разработки Go 1.14 (начало августа 2019 г.), чтобы это уже можно было оценить на практике. В соответствии с процессом оценки предложений, окончательное решение будет принято в конце цикла разработки (начало ноября 2019 г.).


Спасибо за помощь в улучшении языка Go!


Robert Griesemer, для команды Go

Комментарии (25)


  1. ertaquo
    27.06.2019 06:23
    +2

    Значения по умолчанию для аргументов функций и полей структур. Просто дичайше этого не хватает.


    1. Magestro
      27.06.2019 21:51

      В Go, если тебе нужно значение по умолчанию, то ты пишешь для этого отдельную функцию.
      Например:

      func add(a, b int) int {
         return a + b
      }
      
      func addOne(a int) int {
         return add(a, 1)
      } 
      


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

      Например, когда ты читаешь код и видишь:
      driver := app.getMysqlDriver()


      То сразу понятно, о чем речь, а в случае:
      driver := app.getDriver()
      ....
      getDriver(for=mysql) driver{...}

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

      Не уверен, что привёл лучшие примеры, но основная мысль понятна, думаю


  1. voucher
    27.06.2019 07:19
    +1

    Я одного так и не могу понять: будут ли маленькие изменения в языке, которые сломают обратную совместимость? Например,

    • убрать функцию new
    • убрать named return values из функций и методов
    • решить проблему видимости переменной цикла for при ее передачи в анонимную функцию внутри цикла

    Не могу найти, где-то видел доклад одного из разработчиков, который говорил, что есть какой-то способ все-таки внести изменения в синтаксис языка, несмотря на Go 1 Compatibility Promise.

    И вообще, все новости о будущих версиях Go говорят о добавлении новых фич или изменении поведения уже существующих. И пока я не вижу ничего об упрощении и удалении ненужных или неудачно реализованных фич языка и стандартной библиотеки.
    В одном выпуске подкаста Go Time авторы согласились, что новые фичи вообще едва ли нужны, а вот удалить и упростить есть что.


    1. JekaMas
      27.06.2019 07:27

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


    1. TonyLorencio Автор
      27.06.2019 09:12

      Мне кажется, убирать какие-то неочевидные, но дублирующиеся чем-то ещё, или просто ненужные вещи они из языка действительно могут, особенно если это не часто используется людьми (хотя я и не согласен по поводу named return values).


      Но вот изменять текущее поведение чего-то в языке — теперь уже вряд ли.


      решить проблему видимости переменной цикла for при ее передачи в анонимную функцию внутри цикла

      А в чем проблема?


    1. youROCK
      27.06.2019 15:20

      > убрать named return values из функций и методов
      К сожалению, предложение с try() полагается на существование этой фичи, так что вряд ли её уберут :). С другой стороны, лично мне не нравится не столько наличие named return values, сколько сочетание этой фичи с наличием return без аргументов. То есть, я всегда пишу явный список возвращаемых значений, даже если у них есть имена и я просто перечисляю их список в return :). Это позволяет убедиться в том, что я всегда возвращаю zero values в случае ошибок


  1. rustler2000
    27.06.2019 08:33

    image


  1. Gorthauer87
    27.06.2019 09:36

    Интересно почему try а не постфиксный оператор типа? Как в swift или rust.


    1. evocatus
      27.06.2019 12:19

      Ну вы сравнили… Rust это другая вселенная. У них вопросительный знак это синтаксический сахар для работы с обобщённым типом Result, который в других языках известен как Option или Maybe. См. stackoverflow.com/a/42921174

      Конечно, было бы круто, если бы в Go появились типы высших порядков, но это будет уже не Go, а Rust со сборкой мусора, или F#.


      1. snuk182
        27.06.2019 19:20

        У них вопросительный знак это синтаксический сахар для работы с обобщённым типом Result, который в других языках известен как Option или Maybe.

        Option и Result — совершенно разные типы, с разным назначением.
        Option — явная проверка на null, может содержать либо объект обобщенного типа, либо None.
        Result — тип-результат выполнения какого-либо действия, может содержать либо объект-результат успешного завершения дествия, либо объект-ошибку.


    1. snuk182
      27.06.2019 19:29

      В дизайн-документе оно вообще смотрится странно. Если я не зарегистрирую var err error заранее — что произойдет? Куда вернется моя ошибка?
      Реакция на драфт сообщества в виде кучи дизлайков ожидаема.


      1. tendium
        28.06.2019 17:47

        Дизлайков было бы еще больше, если бы они не заблокировали тред.
        Я, кстати, не понимаю, зачем нужен try, если в Go2 планируется вот это?


        1. snuk182
          28.06.2019 18:05

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


        1. rustler2000
          28.06.2019 18:09

          Они check/handle запарятся пропихивать.
          В ближайший релиз оборачиваение ошибок то не смогли пропихнуть, и много кто по существу за Is/As попинывает.
          В фидбэках для try/catch даже отдельную категорию сделали.
          За dep vs mod наверняка многие в недоумение. Стопудово "кость кинули", чтобы более-менее без конфликтов "остался только правильный вариант"



  1. Magic_B
    27.06.2019 12:54

    Я бы очень хотел иметь такую возможность:


    var a int
    var b int
    c := (a = funcA()) + (b = funcB())


    1. TicSo
      27.06.2019 13:48

      вроде так можно:

      c := funcA() + funcB()


      1. Magic_B
        27.06.2019 13:54

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


        1. TicSo
          27.06.2019 14:10

          var a int
          var b int
          
          func f1() int {a=11;return a}
          func f2() int {b=22;return b}
          
          func main() {
          
          	var c = f1() + f2()
          	fmt.Println(a,b,c)              
          }
          


          1. Magic_B
            27.06.2019 14:16

            Есть способы, конечно же! Хочется попроще...


    1. TonyLorencio Автор
      27.06.2019 16:17

      Достаточно высока вероятность пальнуть себе в ногу, если забыть, что операция присваивания ещё и значение возвращает.


      Особенно это будет критично в if-statement (да, случай высосан из пальца, и не так страшен, как в C/C++/Java/..., потому что в в if разрешено только bool, но все равно неприятно):


      if a = false {
              // ...
      }
      

      И после этого нужно постараться найти ошибку


      1. Magic_B
        28.06.2019 07:54

        В любом языке так. В if вряд ли стоит делать проверки типа a == false, это !a и только так.


        1. TonyLorencio Автор
          28.06.2019 08:53

          Понятно, что мой прошлый пример высосан из пальца. А если так:


          var x, y bool
          // ...
          if x = y {
                  // ...
          }

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


          1. Magic_B
            28.06.2019 10:13

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


  1. memba
    27.06.2019 13:13

    Мне не хватает тернарного оператора ?:
    Иногда хотелось бы сделать что-то одной строкой, а не городить громоздкий if.