Как стать автором
Обновить

Комментарии 31

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

И тогда получится Хаскеле-подобный go, на котором уже можно будет наконец то нормально писать.

Или всё просто скатится в C++

С синтаксисом из Паскаля.

есть примеры когда хайлевел язык скатывается в С++ ?

C++

Пусть стек в ошибки завезут. А то иди пойми кто это ошибку кинул, если видишь только текст ошибки.

Эм, ну какбе идиома "кто кидает ошибку: текст ошибки" существует именно поэтому.

иди пойми кто это ошибку кинул, если видишь только текст ошибки

package main

import (
	"errors"
	"fmt"
)

func main() {
	err := some()
	if errors.Is(err, ErrSome) {
		fmt.Println("ok")
	}
}

var ErrSome = fmt.Errorf("some error")

func some() error {
	return fmt.Errorf("text containing additional information about the execution context: %w", ErrSome)
}

Ну если у вас в проде такой код то оно конечно да. А когда кода на 10К строчек, разные слои и флоу... и ошибка прилетает откуда-то очень изнутри, из какой нибудь библиотечки, в то удачи вам в 3 часа ночи на блокере разобраться что случилось. А если ошибка еще и с динамическим текстом то все еще веселее.

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

Не вижу никаких проблем со слоями. У нас в проектах используется чистая архитектура.

и ошибка прилетает откуда-то очень изнутри, из какой нибудь библиотечки

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

удачи вам в 3 часа ночи на блокере разобраться что случилось.

Если у вас слоёная архитектура, то такие кейсы достаточно легко покрыть тестами.

А если ошибка еще и с динамическим текстом то все еще веселее.

Можно конкретный пример? Не совсем понял.

чем посмотреть на стэк и понять где проблема началось и откуда конкретно прилетела ошибка.

Не удобнее. Например когда паникует гороутина, по стеку не всегда понятно от куда она была вызвана.

Проблемы с пониманием причин ошибки в основном связана с повсеместным использованием

if err != nil { return err }

Вместо того чтоб потратить время, добавить обёртку с расширением контекста fmt.Errorf() или как-то обработать ошибку.

Приведите пример кода, где сложно понять по ошибке где она произошла. Я проведу ревью и попробую предложить своё решение.

Предполагается что ошибки будут оборачиватся друг в друга, в общий стек.

// при ошибке будет: "b call failed: c call failed: bad connection"

func a() error {
  err := b()
  if err != nil {
    return fmt.Errorf("b call failed: %w", err)
  }
  return nil
}

func b() error {
  err := c()
  if err != nil {
    return fmt.Errorf("c call failed: %w", err)
  }
  return nil
}

func c() error {
  return errors.New("bad connection")
}

И где тут стэк? Иди ищи по коду кто кого там вызвал. Это ад.

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

Из-за безисходности некоторые начинают панику кидать что бы иметь стэк... ну и вроде как библиотечки какие-то есть. Одним словом, мыши плакали но продолжали есть кактус.

И предположение что все ну прям будут оборачивать все и вся... ну может в етнерпрайзе.

То что у вас ошибки не обработаны, это не проблема Go.

Понятно что проблема наша. Но в любом нормальном языке стэк экономит кучу дорогого времени.

В 99% случав обработка ошибок это как тут уже написали

if err != nil { return err }

Можно все делать правильно что б по книжачке. Но реальность она другая немного.

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

Вы вполне можете сделать это сами, сделав свой тип ошибки со стеком, используя runtime.Callers для получения стека. Или воспользоваться уже готовым пакетом, например, go-errors/errors.

Я имею ввиду человеко-читаемый стек.

Предположим что нашу CLI тулзу эксплуатирует некий админ, который на сервере её запускает.

Если нормально оборачивать ошибки, то при запуске он увидит что-то такое:

"failed start: failed preload data: failed query data from db: port 5050 unreachable: connection refused"

и он в целом сможет понять чего именно тулзе нехватает (например нужно открыть какой-то порт).

если не оборачивать ошибку, всё что он увидет это "connection refused". Абсолютно бессмысленная ошибка, которая ничего не говорит.

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

connection refused at:
- db.go:14
- repository.go:32
- loader.go:68
- cache.go:16
- main.go::34

Лучше чем ничего, но хуже чем нормальная человеко-читаемая ошибка.

b call failed

Не стоит в тексте писать failed и error. Сам тип говорит о том что произошла ошибка.
В контексте лучше прописать что именно было сделано.

В данном случае просто call c, call b. Иногда полезно бывает добавить значения входящих параметров.

Некоторые вовсе сокращают до b: c: couldn't connect

Констрейты так-то есть. Чтобы использовать тип внутри дженерика его как раз и надо указать. https://go.dev/blog/intro-generics

Для «хаскеле-подобобия» не хватает синтаксического сахара и чего-то типа sealed типов с проверкой инварианта компилятором :)

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

Да я то на Хаскеле и пишу, но вот беда работу трудно бывает найти. В го соотношение вакансий/соискателей получше...

Так, может лучше нести Хаскель в массы, чтобы появлялось больше вакансий? Тут доклад, там доклад, сравнение решения на Го и на Хаскеле, например. А, может, и перформанса приложения. Глядишь начнут задумываться, что может ФП и хорошо и надо больше в его сторону идти. Ну или массово будут переходить на Хаскель или прочие языки активнее начнут завозить к себе всё, что нужно для ФП.

Кстати, например, вот Скала - смесь ООП и ФП, даже сообщество раскололось. Один за чистое ФП, другие за ООП с элементами и ФП. Ну и в итоге первые ушли на Котлин и некоторые на Го, количество вакансий сократилось. Ну и смысл в ФП? :)

Ну и к тому же, допустить ошибку в таком сплаве парадигм легче и потом сиди и думай, почему в этом месте uuid/временные метки все разные, а тут, этот же скопированный код, всегда отдаёт один и тот же uuid/время. Ладно кто понимает как и что работает, то что ниже используется, а новичку совсем от этого грустно становится.

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

Да, согласен, Скала местами очень запутанная.

F# пробовали? Функциональный язык от мира .NET

Я вот не пробовал, поначалу останавливало, что он Windows only, а потом, как-то всё руки не доходили. Но вижу, что .Net активно развивается, но в первую очередь C#.
А как по вакансия на F#?

А вообще конечно грустно что в Го так много функций в global scope.

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

https://github.com/samber/lo - да да, это лодаш для го

В чем проблема завезти ну хотя бы obj?.optionlField?.optionalfield

Сделайте не нуллабл поля а структуре и это будет работать

И требовать ничего не надо

Если бы это было удобнее, у этой либы не было бы 12к звездочек и 500 форков.

Понятно что всегда можно вырулить. А пока что, я мечтаю о GO но пишу на TS.

Простые вещи должно быть просто делать.

Языки программирования совершенствуются, но ошибок в конечных продуктах меньше не становится.


Захожу на ваш сайт https://cashback.mts.ru, подвожу курсор мыши к вкладке Потратить, и в этот момент вся страница еще раз перезагружается.


Этому багу год, не меньше. Ну что за ...

Кто нибудь понимает, почему clear для слайсов так работает?? Что мешает обнулять так же строки в массивах?? Вообще стандартные структуры данных очень странные в go, в особенности из за всяких тонкостей с инициализацией с помощью make....

Зарегистрируйтесь на Хабре, чтобы оставить комментарий