Pull to refresh
143
19
Искандер @quasilyte

store.steampowered.com/app/3024370/NebuLeet

Send message
Мне приятнее писать на статически типизированных языках.

А Go тут при чем?


При том, что мне нравится Go. :)


Не подумайте, что это хейт в вашу сторону, это вовсе не так. Я просто не особый фанат GoLang'a.

Когда дело касается языков программирования, как-то всё резко скатывается в холивары. Мне Go нравится, вам — нет. Мне недостатки Go знакомы, но мне с ним вполне комфортно.


Кстати, я пытался сделать на основе самого Emacs Lisp свой диалект, но это тоже довольно быстро привело к тому, что нужно писать свой language mode, а это не так весело. Думаю каждый энтузиаст Emacs Lisp делал такое хотя бы раз в жизни. :)

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


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


Я не вижу бенефитов от Go для Emacs'a ну вот вообще.

А я вижу. :)
Мне приятнее писать на статически типизированных языках.
Не всегда нужны все фичи из Emacs Lisp, типа макросов.
Мы имеем право не сходиться в этом мнении.


Хотя лично я уже года 2 на Emacs Lisp ничего не пишу, поэтому "проблема" сама собой исчезла. :)


Как раз таки большинство пользователей сидят на Емаксе из-за лиспа в том числе.

У меня такой статистики нет, но все мои знакомые емаксеры либо очень плохо знают Elisp, либо вообще его только на уровне copy/paste использовали. Ваш опыт может здесь расходиться, но я описал картину, которую я наблюдаю.


Если вам уж так нравится Go, пишите на нем плагин/мод или я знаю что еще и общайтесь с ним через фронтенд емакса (аля lsp только для вашего плагина).

Я описывал альтернативы в статье, общение с Emacs через процессы или плагины там есть. Правда плагины мне казалось, что называются модулями.


Таким образом плагин можно будет переиспользовать, для вима например (наверное), ну или там для других редакторов (профит)

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

Есть чатик https://t.me/noverify_linter, где обсуждаем статический анализ и сам NoVerify.


В идеале это должно стать community чатом проекта, где голоса пользователей и контрибьюторов могут быть услышаны более оперативно и в менее формальной обстановке, чем GitHub issues.


Присоединяйтесь, если интересен статический анализ PHP (другие линтеры там тоже обсуждаем и сравниваем). :)

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

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


Нужно учитывать, что это линтер для PHP, а Go здесь — деталь реализации. Поэтому требовать от людей наличия Go тулчейна для использования этой фичи может быть слишком. :)


Компиляция шаблонов — это оптимизация, а пока у нас нет проблем с производительностью. Даже если умножить на 10 количество текущих шаблонов, работает очень быстро, при этом нет гарантии, что у нас когда либо действительно будет x20 шаблонов.


Например, для шаблона $_? $x: $x; кажется известно заранее какой конкретный узел AST «слушать».

В текущей реализации тоже не сложно запускать шаблон только для тернарных операторов. По-моему сейчас он в группе условных выражений, но не сложно довести отображение к 1-to-1, но опять же, рановато оптимизировать, как по мне.


Динамика просто удобнее или есть технические препятствия?

Я бы сказал, динамика даже мне удобна для отладки, когда экспериментируешь. Компиляция шаблонов была бы интересной дополнительной фичей, но вытеснить динамические правила она, думаю, не должна. Для совсем-совсем критичных к производительности проверок всегда можно написать обычное расширение линтера на Go, без использования "правил".

Telegram, Google, CloudFlare, EFF, AccessNow, Tor Project, Linux Foundation, Canonical, Docker?

Всё же, это не универсальный список. Почти любую из компаний этого списка найдётся за что не любить некоторым людям. Например, вы можете довольно легко на хабре найти относительно новые статьи, где разработчиков Telegram обсуждают в очень негативном ключе. Google — тоже не для всех корпорация добра. Работать в Linux Foundation или Tor Project — это не звучит, как выбор для многих людей, я не проверял, но не уверен, что у них очень много открытых вакансий.


Ещё учтём, что в наших реалиях работать на компании из Европы/США затруднительно, некоторые из них не работают с РФ по политическим причинам.


Чтобы мысль не потерялась: на кого вы не работайте, найдётся тот, кто не будет вас "уважать". Ставить цель быть "многоуважаемым человеком" может быть вредно, вот такое моё скромное мнение.

Несколько раз замечал стажёров в офисе, но до взаимодействия не доходило. :)


Мой коллега рассказывал на одной из демонстрация для стажёров чем занимается наша команда (backend инфраструктура), хотя ни одного стажёра мы в тот момент так и не взяли.

Добавлю ещё:



Не для начинающих, но может быть полезно и Go-specific:


Спасибо!


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


Сложно судить, насколько такой подход в PHP распространён, на корпусе из статьи 709 использований, а у preg_match — 5486 (при этом не все из них разбирают URL'ы). Но вроде бы достаточно часто используется. :)

Возможно, если регулярка уже не читабельна и при этом всё равно посредственно справляется с задачей, хорошо бы URL распарсить какой-нибудь либой и проверять домен или другую интересующую часть через switch/мапу/ifelse.


Я не эксперт в PHP, но в Go есть url.Parse, например.


u, err := url.Parse(urlString)
if err != nil {
  // URL не валиден.
}
switch u.Host {
case "blah.com", "foo.com":
  // Good.
default:
  // Опционально обработать остальные урлы.
}

Если "слишком много кода", то можно это в функцию завернуть.

phpgrep всё же не столько про инспекции. Вы можете с помощью него упрощать рефакторинг, поиск bad practices по вашим собственным правилам. Ещё можно узнавать ответы на вопросы: "как часто в нашем проекте эта функция вызывается с определённой комбинацией аргументов?" или "есть ли у нас места, где тяжёлая для вычисления функция вызывается в цикле?".


Такой анализ можно выполнять и без phpgrep, но это потребует либо больше кода, либо ниндзюцу с регулярными выражениями (если попробуете грепать).


Есть шанс, что позже добавлю опцию replace, чтобы не нужно было руками всё заменять.

В языках, где = не является выражением, yoda style является нежелательным. :)
От этого обидно, что в PHP приходится такое использовать как защиту от ошибки. Но есть линтеры, которые найдут подозрительные применения присваиваний, так что иногда проще сделать линтеры на CI построже, а код оставить читабельным.


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


В go-critic даже проверка есть, yodaStyleExpr, которая просит переписать в нормальную запись.

Возможности такого анализа ограничены.


Это подходит для прототипирования, но не для production решения. Хотя если аккуратно написать шаблоны, должно помочь.


while ($percentage == '100')

Скорее всего, тут сработало сравнение со строкой через == вместо ===. Это не очень хорошая практика.

2) При повторном оборачивании ошибки (например, на уровень выше), стектрейс затирается менее информативным.

Это верно. Нет нормального способа "добавить стек, если его ещё нет". Но всё же у вас неточность.


Стек скорее не затирается, а дополняется. Если внутри одной горутины, будет дублирование, которое можно при печати самой ошибки убирать, примеры есть внутри pkg/errors, но если из разных горутин, то стеки будут различаться.


3) При каждом оборачивании обязательно передавать дополнительный текст ошибки, что мне кажется некоторым оверхедом при написании/чтении кода.

Есть WithMessage, который добавляет только сообщение, а есть WithStack, который добавляет только стек.

Спасибо за серию статей! Чуть не упустил её, но поймал на финальной части. :)

Быстрее выделение, быстрее очистка, не увеличивает объём работы для GC.
А ещё по времени выполнения более детерменированно.


То, что в Go есть типы-значения (то, что можно использовать не по указателю), позволяет больше всего на стеке размещать, что может иногда сильно помогать.


Escape analysis правда до сих пор многие вещи не распознаёт, но у Matthew Dempsky как-то делился своим полным переписыванием этой части, может, её дорабатывать будет проще. :)

Лучше запускать компиляцию с флагом -gcflags='-m=2', тогда будет понятно, что происходит с аллокациями, что идёт в кучу, а что на стек:


foo.go:16:13: new(bytes.Buffer) escapes to heap
foo.go:16:13:   from buf (assigned) at foo.go:16:7
foo.go:16:13:   from buf (interface-converted) at foo.go:17:21
foo.go:16:13:   from buf (passed to call[argument escapes]) at foo.go:17:21

Даже если у вас new(bytes.Buffer) внутри case, он будет размещён на куче. Когда buf передаётся в качестве io.Writer, будет безусловная аллокация.


Вообще interface{} с производительностью слабо совместим.
Множественные case в type switch плохи как минимум тем, что туда значение пробрасывается как interface{}.


Если нужна скорость, сделайте числовые типы первыми и используйте для (u)int16/32/64 методы binary.BigEndian.PutUint16/32/64 напрямую.
Это может быть эффективнее.


Учтите, что type switch выполняет ветки последовательно, поэтому более частые типы стоит ставить первыми.
Для числовых типов вы вполне можете сделать пути выполнения без лишних аллокаций.
Слайсы, выделяемые в "buf := make([]byte, 4)", где размер заранее известен, Go спокойно размещает на стеке (но в этой функции буфер убегает через return, так что всё равно ему место в куче).


Вот пример для специализации ветки uint64: https://play.golang.org/p/1srtJDsIFIJ.
Разница в производительности:


$ go-benchrun Old New -benchmem -count=10
  Running old benchmarks:
goos: linux
goarch: amd64
BenchmarkOld-8       1000000          1402 ns/op         816 B/op         11 allocs/op
BenchmarkNew-8      50000000            24.3 ns/op         8 B/op          1 allocs/op
PASS
ok      _/<ВЦ>  12.802s
  Benchstat results:
name   old time/op    new time/op    delta
Old-8    1.42µs ± 5%    0.03µs ± 3%  -98.24%  (p=0.000 n=10+10)

name   old alloc/op   new alloc/op   delta
Old-8      816B ± 0%        8B ± 0%  -99.02%  (p=0.000 n=10+10)

name   old allocs/op  new allocs/op  delta
Old-8      11.0 ± 0%       1.0 ± 0%  -90.91%  (p=0.000 n=10+10)

Надеюсь, это является ответом на ваш вопрос.

Готово. А ещё приглашаю в канал #gocontributing в слаке, если вам там ещё нет. :)

О, об этом я как-то не подумал. Хорошее дополнение, спасибо!

Я тогда допишу в скором времени в этой же статье.
Зачем в этой статье логотипы VK?

В основном потому что мне захотелось его туда добавить.


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


Секцию "о себе" в первый раз использовал. Возможно слегка переборщил и можно было без самого лого, одного лишь талисмана оставить.

Значит я плохо описал. :)

Идея в том, чтобы найти какие ошибки вообще совершались в некоторых проектах, чтобы диагностировать их в будущем, в том числе в других проектах. Плюс если у нас есть reproducer (пример кода с дефектом), проще делать тесты для линтера.

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

Надеюсь, так понятнее.

Information

Rating
642-nd
Location
Грузия
Registered
Activity