• За что я не люблю Go
    0
    Это как-то делает то, что в Go становится сложно? Еще раз, разговоров о том, что в Go очень просто и удобно писать конкурентный код (горутины, каналы, контекст).
  • За что я не люблю Go
    0
    напомню что разговор был не про «короче», а про «просто». Я сказал, что очень просто запустить горутину (к этому прицепились сразу) и управлять ее, и взаимодействовать (каналы).
  • За что я не люблю Go
    0
    Я умываю руки, продолжайте и дальше бороться со своими мельницами. Удачи.
  • За что я не люблю Go
    0
    Не надо лукавить! А где запись в канал?

    В функциях getData1 и getData2, но даже вы не показали что там внутри.


    У этих функций не было такого параметра, это могла быть какая нибудь http.get(), которую нельзя было доработать.

    Раз уж вы еще больше выдвигаете требований, можно так:


    ch1, ch2 := make(chan string), make(chan string)
    go func() { ch1 <- getData1() }()
    go func() { ch2 <- getData2() }()
    result = foo(<-ch1, <-ch2)

    Но сути это не меняет.

  • За что я не люблю Go
    0
    ch1, ch2 := make(chan string), make(chan string)
    go getData1(ch1)
    go getData2(ch2)
    result = foo(<-ch1, <-ch2)
  • За что я не люблю Go
    0
    Дело в том, что эту ситуацию описывают как проблему рантайма или планировщика, что не так (даже если планировщик будет уметь приоритеты, все равно может быть все горутины с одинаковым приоритетом).

    Конечно же такая ситуация может быть и часто, но еще раз — все потоки выполняются и не заблокированы. Если такая ситуация появилась — нужно либо оптимизировать алгоритм либо скейлить.
  • За что я не люблю Go
    0
    Выше было сказано, что код «ставит колом целиком поток», а это не так (все потоки выполняются). Значит неправильно понимают (может я непонятно выразился с «воспринимают»). Но сути дела это не меняет.
  • За что я не люблю Go
    –1
    Я лишь указал вам на вашу ошибку в восприятии того кода выше (с бесконечным циклом).
  • За что я не люблю Go
    0
    У меня?
    Еще раз напишу — с точки зрения рантайма все хорошо, все рутины работают и не заблокированы, проблема только в вашем коде.
  • За что я не люблю Go
    0
    Смотря как вы будете формировать отчет — вам нужно будет его откуда-то читать, да? Построчно? Вот вам уже и сисколы, уже будет переключение горутин.

    Но давайте так, допустим каждая горутина просто должна спать 1 минуту (ну типа чисто в памяти что-то 1 минуту считаем, без сисколов). Сделав 9 запросов, девятый будет ждать. Только это не проблема языка или рантайма, с точки зрения рантайма все очень даже хорошо — все тредэ ранятся и нету заблокированных.
  • За что я не люблю Go
    0
    Ну да, тред работает, только остальные горутины остались в пролете. Бесконечный цикл скорее всего исключение, но вот долгое выполнение вполне реально может случиться. Пользователю то пофиг, тред твой тормознулся или занят непонятной херней, ему главное чтобы сайт не тормозил, а вместо этого получит 503.

    Вы написали бредовый код и пытаетесь натянуть его на реальную картину — нет, так не работает.
    Пишите код, который не будет выполнять непонятную херню.
  • За что я не люблю Go
    0
    Если вы заговорили о пользователе, то давайте реальный пример, а не бесконечный цикл.

    Сейчас, с точки зрения, что говорил qrKot, у вас ничего не произошло, все потоки ранятся.
  • За что я не люблю Go
    0
    Вы же понимаете, что в вашем примере с потоком ничего не произошло?
  • За что я не люблю Go
    0
    Да я откуда знаю, может есть еще и другие способы. Тем не менее, это работает не так как написал qrKot. Это не плохо и не хорошо, это примерно также как и у других.


    А как? Ваш пример был ошибочным, трэд там в состоянии Running и то что сказал qrKot подтвердилось вашим же примером.

    Вы так говорите, как будто это уникальная фича go, да у всех асинхронных серверов так. Понятно что в старых языках типа Java остались синхронные апи для I/O, ну сам себе буратино что используешь их в асинхронном методе. Ну кстати не всегда и требуется переписывать на асинхрон, я как-то переписал консольную утилиту и она стала медленнее работать, накладных расходов потому что стало больше чем полезного кода.


    Я не говорю про уникальность, это тут все любят сравнивать, я вам привел пример как сделано в Go. При этом асинхронный I/O это совсем другое (был как пример).
  • За что я не люблю Go
    0
    Вы уже уходите от темы, то есть вы согласны что «никакая горутина не может поставить колом целиком поток»?

    Конечно же есть затраты на парковку goroutine и context switch (стэк, кстати, у каждой горутины свой и алоцируется при создании), но это ничтожно мало с, например, ожиданием I/O. Как уже говорили, Go хорошо подходит для Web.

    Вот в Go, за счет того, что заблокированая горутина паркуется и не блокирует трэд, второй запрос у вас обработается быстрее, так как во время I/O первой горутины, будет выполняться вторая.
  • За что я не люблю Go
    0

    В реальном мире да, когда в той же Java на ожидание ответа системного вызова блокируется весь поток.


    Чуда не произошло в вашем чудном примере.


    UPD: "поставить колом целиком поток" не тоже самое, что поток будет исполняться. Поставить колом — это блокировать, например.

  • За что я не люблю Go
    0

    А чего вы хотите увидеть? Я пока вас не понимаю.
    В Go кооперативный (почти) планировщик, планирует goroutine по доступным тредам — у вас 8 goroutine не блокируются, не делают системных вызовов, просто инкрементят счетчик, всегда в running состоянии.


    Только вот в реально мире такого не будет. Вот добавьте всего одну строчку (fmt.Println(t) в цикле функции test) и у вас совсем другой результат.


    func main() {
        for i := 1; i < 100500; i++ {
            go test(0)
        }
        time.Sleep(1)
        go fmt.Println("main 1")
        fmt.Println("main 2")
    }
    
    func test(t int) {
        fmt.Println("start")
        for true {
            t = t + 1
            fmt.Println(t)
        }
        fmt.Println("stop")
    }
  • За что я не люблю Go
    0

    А зачем вы добавили runtime.GOMAXPROCS(1)?

  • За что я не люблю Go
    0
    То что в го есть только корпоративная многозадачность

    В Go не совсем кооперативный планировщик (https://github.com/golang/go/issues/10958), а еще есть предложение — https://github.com/golang/proposal/blob/master/design/24543-non-cooperative-preemption.md


    Но не думаю что будут менять радикально что-то.

  • За что я не люблю Go
    0
    1. Не знаю что там в C#, говорю как удобно в Go (опять же начались примеры в стиле "а вот в X языке точно такая же фича"). Ну и даже краткость записи — уже ведь лучше, да? Ведь тут все хейтят Go с if err != nil. В вашем примере мне не понятно, что такое Task, это ваш класс или со стандартной библиотеки?


    2. Можно сделать все что угодно, только вот в Go это часть стандартной библиотеки (как и пакеты context и sync для управления goroutine).



    В сумме все это очень упрощает написания конкурентного кода.

  • За что я не люблю Go
    0
    Связка tokio+futures-await так же удобны в использование как горутины.

    Прям вот точно также удобны?
    Удобство goroutine в том, что их просто стартануть (go перед любой функцией/методом) и то, что есть каналы для их взаимодействия. В Rust тоже есть каналы?

  • За что я не люблю Go
    +2

    Я уже почти 4 года программирую на Go: мне не нужно генерировать шаблонный, мне не нужны дженерики, уже давно есть удобный пакетный менеджер (сейчас еще модули завезли), компилятор очень сильно помогает (зависит с чем сравнивать, да?). В основном я пишу/писал web сервисы (нагрузка от 30к до 400к RPS), стрим процессинг с Kafka, тулзы для Kubernetes, etc.
    Мне нравится Go, мне нравится вот это if err != nil, после Java я совсем по другому начал относится с ошибкам.


    И я совсем не понимаю, почему пользователи Хабра в каждом посте про Go начинают бегать туда-сюда с криками насколько Go ужасный язык, при этом 80% из них на Go не программируют. Начинают сравнивать отдельные фичи Go с фичами других языков — а вот в Х яызке это лучше, а вот в Y языке другое лучше:
    — Но я использую Go, мне нравится X фича и для моих задач Go подходит идеально. Тем более у нас есть опыт на Go.
    — Ты не понял, Go говно, там if err != nil, вот тебе Rust/C++/Haskell/JavaScript там еще лучше. Монад ведь нету в Go? Воот, ерунда ваш Go.


    В каждом посте овер 200 комментов, больше половины из которых вот такие бессмысленные срачи.

  • За что я не люблю Go
    0
    Да согласен.
    Я все время ссылался на эту доку, про то, что вы писали так и не нашел.
  • За что я не люблю Go
    0
    То, о чем я говорю
    fn call<F>(a: i64, _b: i64, c: F) -> i64
    where
        F: Fn(i64) -> i64,
    {
        c(a)
    }
    
    fn main() {
        let example_fn = |a| a;
        println!("{}", call(10, 10, example_fn));
    
        println!("{}", example_fn(String::from("hello"))); // ошибка
    }
    


    Тип example_fn определился при первом вызове.
  • За что я не люблю Go
    0
    В примере выше вывод типа происходит у аргумента замыкания. В примере с функцией call, так же вывод типа происходит у аргумента замыкания за счёт того, что в сигнатуре функции явно указан тип аргумента замыкания.

    Можете дать ссылку на документацию?


    Потому что в примере:


    let example_fn: &Fn(String) -> String = &|a| a;
    println!("{}", example_fn("Hello, world!".into()));

    Вы же указали тип функции и тип аргумента функции, вот же он &Fn(String). Функция example_fn ждет первым аргументом String. Если там не String — то ошибка компиляции.


    Ваш изначальный пример — это свойства анонимных функций, а не вывод типа анонимной функции из сигнатуры.

  • За что я не люблю Go
    0
    Сейчас я еще больше запутался, чем тогда это отличается от Go?
    ```go
    func main() {
    example_fn := func(x string) string { return x }
    print(example_fn(«hello»))

    example_fn2 := func(x int) int { return x }
    print(example_fn2(10))
    }
    ```

    Как раз в первом варианте (тот что с callback), там выводится тип анонимной функции по первому использованию и после этого выведенный тип удовлетворяет сигнатуру функции **call**.

    Можете кинуть ссылку на документацию по этому?

    UPD: как раз в Go тип переменной вывелся из присваиваемого значения.
  • За что я не люблю Go
    0

    Тип анонимных функций определяется при первом использовании. Потому, если я все правильно понял.
    Вот у вас функция: println!("{}", call(10, 10, |a, b| a + b));, а вот тут первое использование — c(a, b).
    a и b имеют тип i64, потому у этой анонимной функции будет тип Fn(i64, i64) -> i64, а не потому что в сигнатуре where F: Fn(i64, i64) -> i64.


    let example_fn = |a| a;
    println!("{}", example_fn(String::from("Yo"))) // вот тут уже будет тип Fn(String) -> String
    
    let example_fn2 = |a| a;
    println!("{}", example_fn(2)) // вот тут уже будет тип Fn(i64) -> i64
  • Kotlin Native: следите за файлами
    0
    В Go я делаю вот так `GOOS=linux go build` и запускаю бинарник на сервере. А как это сделать с python?

    > Необходимость собирать в бинарник или использовать virtualenv (я предпочитаю этот вариант) это больше неудобство, чем проблема.

    Так разве удобство это не преимущество?
  • Kotlin Native: следите за файлами
    0
    То есть вы мне предлагаете сделать что-то (как virtualenv или собрать python в бинарник) вместо того, чтобы ничего этого не делать и называете это преимуществом?
  • Kotlin Native: следите за файлами
    +1

    Отсутствие зависимостей всегда лучше их наличия и ansible тут не панацея.


    1. Тулзе А нужна 2.2 версия, а тулзе Б 3.1. Блин, надо virtualenv настраивать?
    2. Потом pip или yum — чем мы там python зависимости ставим? А уже везде дефолтная версия python3? Ахх, тут на 100 серверах yum'ом установили, а на другой сотне pip'ом.
    3. Блин, ansible yum модуль поставил библитеку libA-2.3.0 хотя я явно же написал поставить libA-1.9.0 (ох state: latest игнорит версию в названии пакет).
    4. Блин, OS команда не дает нам root (не доверяют), а мне надо бы новую зависимость установить, опять virtualenv настраивать, а как же с C зависимостями?

    И так далее.


    Преимущество есть и оно большое (может быть конечно не "невообразимое").

  • Kotlin Native: следите за файлами
    0
    А нужные библиотеки могут там не стоять
  • Kotlin Native: следите за файлами
    –1
    Я пытался провернуть такое с traefik, но схема собери и запусти не работает без настроенного рабочего окружения с этими всеми GOPATH и прочим.

    А говорят в Go очень низкой порог вхождения, оказывается не такой уже и низкий.
  • За что я не люблю Go
    0
    Если я правильно понял, то в Rust это не вывод типов, а то как работают замыкания — типы (сигнатура) определяется при первом использовании замыкания.

    UPD: хотя да, это вывод типа анонимной функции, но не потому что в аргументе c функции call указаны все необходимые типы для колбэка.
  • За что я не люблю Go
    0
    А, кстати, как, если дженериков или рефлексии (что рантайм, что компилтайм) нет?

    encoding/json использует рефлексию.

  • За что я не люблю Go
    +1
    Да нет, как раз вы добавляли условий, потому что вас не устраивали ответы и вы пытались подогнать все под свою позицию. При этом вы будете игнорировать безопасность, высокодоступность, чтобы только подогнать все под ваше решение.
  • За что я не люблю Go
    0
    В моем случае это был Azure. Там проблем бтв тоже не было.

    azure.microsoft.com/en-us/status/history

    А это уже зона ответственности PaaS-платформы, которой вы пользуетесь.

    Я ее разрабатываю.
    Но не все пользуются облачными платформами, не у всех 1 rps нагрузка и так далее. Вы тут подобрали специальные условия и представляете свое решение как единственно правильное учитывая только ваши условия.
  • За что я не люблю Go
    +2
    В дотнете риск существует только при обновлении.

    Вы сейчас это серьезно?
    Не надо сейчас придумывать, что там принято в Go.
    Вот эта ваша самоуверенность удивляет — проблемы могут быть везде, начиная от железа, проблем сетью и до того, что админ или вы случайно кильнете ваш сервис. Но у вас «В дотнете риск существует только при обновлении.».
    Магия, не иначе.
  • За что я не люблю Go
    0
    Ага, а еще у вас уязвимостей в библиотеках нету. /s
    Надежда это не стратегия, то что вам повезло, не означает, что вы правильно все делали.

    ОС я так понимаю вы тоже не обновляете?
  • За что я не люблю Go
    0
    Ну я же написал еще «толку с ваших стратегий по обновлению конфига, если у вас упал один инстанс и уже даунтайм».
  • За что я не люблю Go
    0
    Предлагаете делать кластер просто чтобы конфиги перегружать?

    Предлагаю всегда иметь HA, иначе это уже не серьезно.

    Толку с ваших стратегий по обновлению конфига, если у вас упал один инстанс и уже даунтайм.
    HA это про доступность сервиса.