Pull to refresh
3
0

Разработчик

Send message

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

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

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

Окей, тут согласен. Давно не писал, возможно так и было. Впрочем, вопрос boilerplate остаётся, хоть и не так остро.


И чем при выходе из скопа не устраивают defer тогда?

Всем устраивает. Кроме того, что последний раз, когда я имел дело с Go, компилятор никак не предупреждал, что я его пропустил. Или ситуация поменялась, и я напрасно ною?

Л — логика…

Я вам наступил на любимый мозоль, что вы мне аж по карме прошлись?


Поэтому спросил, для каких задач вам захотелось деструкторов и использовали ли вы финализаторы.

Боже, ну почему все так вцепились в слово "деструкторы"? Я уже в нескольких ветках написал, что было бы приятно иметь хотя бы ворнинг "здесь может утечь ресурс, поставь defer".

вроде Item, у которого есть один метод Less — для сравнения значений

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


В Джаве 1.5 тайп-касты же всё равно происходят, но автоматически, неявно, насколько я понимаю.

Да, происходят. На это ругается множество людей с самого выхода 1.5


Мне кажется, вы сильно переоцениваете роль компилятора :) С какой стати у вас должен быть сегфолт, если вы не проверили ошибку?

Как бы


val, err := someOp()
// здесь забыли вставить if err != nil { ... }, компилятор промолчит
val.field.fieldOp() // привет паника - или сегфолт, уже не помню

Память сборщик мусора почистит, понятное дело, но defer используется для того, чтобы выполнить какие-то действия при выходе из скопа

Кроме памяти есть ещё множество типов ресурсов. Самые простые — файлы и сокеты. И для многих из них хотелось бы точно знать, что они будут закрыты при выходе из скопа. Проблема даже не в необходимости явной инструкции для такого закрытия. Проблема в том, что компилятор в этом не желает помогать.

То есть по другим трём пунктам вопросов нет? :)

Хорошо, давайте попробую привести примеры. Сам код, увы, сейчас мне недоступен.


как именно вы не смогли "переиспользовать код" и к чему это привело из-за "отсутствия дженериков"

Стейт-прокси над стейтлесс сервером. Часть, ответственная за кеширование, была отделена от других кусков кода. Снаружи пришлось "просовывать" объект в виде interface{} и лямбду, которая его кастила к правильному типу и дёргала. Да, это непривычно для меня — я отвык от тайп-кастов по поводу и без с тех пор как перестал писать на голом С. Более общий пример — в Го любая не-встроенная структура данных будет построена на interface{}. Опять тайп-касты. В Java такая ситуация была до 1.5, после чего дженерики, хоть и урезанные, таки ввели.


как нынешняя обработка ошибок приводит к проблемам в коде

Как я сказал, конкретный код привести сейчас не могу. Был код такого вида, способный "обломаться" на любом этапе:


val1, err := op1()
if err != nil { return nil, err; }
val2, err := val1.op2()
if err != nil { return nil, err; }
val3, err := val2.op3()
if err != nil { return nil, err; }

В добавок, если я забуду обработать ошибку, компилятор мне слова не скажет. И у меня будет NPE паника или сегфолт.


Для сравнения, на любом языке с исключениями:


return op1().op2().op3;

На Rust, который тоже работает через возвращаемые значения


op1()?.op2()?.op3()?

Может ещё конструкторы, ещё и с перегрузкой?

Вот кстати с отсутствием конструкторов как "специальных функций" я полностью согласен. Ловля нетривиальных проблем с порядком инициализации и "самоубийства" в С++ при исключении в конструкторе (а особенно в одном из инициализированных по умолчанию полей) — удовольствие ниже среднего. Перегрузка функций и методов по типу аргумента — дело скорее вкуса. Может быть удобна, но может быть и использована криво.


Обычно если "хочется деструкторов", то это вы ещё не отвыкли от предыдущих языков

Defer совершенно другую задачу решает.

Таки да, я привык, что если я открою какой-то ресурс и никуда его не дену — он сам помрёт без моего участия, в конце области видимости. По поводу же defer — а какую в таком случае задачу он решает? Разве не очистку в конце блока? Впрочем, меня вполне устроило бы предупреждение от компилятора, если я забываю почистить ресурс.

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

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

Всё же надеюсь, что некоторые элементы в Go 2 введут. Я бы лично не откзался от четырёх


  • Generics — дабы иметь инструменты переиспользования кода
  • Result-like обработка ошибок, дабы не иметь проблем с "вернули не-окей и забыли обработать", вкупе с кодом забитым
    val, err := func()
    if err != nil {
    return <default value>, err
    }
  • Non-nullable ссылки по умолчанию. Nil non-nil interfaces это честно говоря жёсткий косяк. Вопрос того, ссылки в Го или указатели, на самом деле дискуссионный.
  • Деструкторы в каком-то вменяемом виде. defer не очень способствует надёжному коду.

К слову, epoll(0), или BUSY_WAIT приводит к тому, что еполл сразу возвращается, независимо от кол-ва сработавших событий. Это приводит к тому, что текущий поток крутится в чём-то наподобие спинлока вместо того, чтобы сразу отдать остатки кванта. И да — это даёт прирост — но только в очень конкретных сценариях. И таки да, в нормальном продакшене так не делают, т.к. вместо прироста будет просадка.

Это был не я.

Да, точно. Извиняюсь.


Именно про это я и говорю, но. Конкретные оптимизации зависят от языка и я, так же, сказал почему.

Я спорю именно с тем, что оптимизации — это какая-то вещь в себе. Нет. Для оптимизаций нужны возможности, в том числе, со стороны языка.

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

Эээ… ну да, я согласен. Засим, думаю, ветку можно прикрывать.

Мне понравилась идея, предложенная на следующий хайлоад. Постепенно поднимать RPS. Выиграет тот, кто дольше всех проживёт, не выходя за SLA.

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


Вы начали с того, что топовое решение на Rust попало только на 31-е место, а вот на Go — аж на 15-е (потом поправили что на 11-е).


Я возразил, что на таком уровне вопрос уже не в языке, а в конкретных оптимизациях.


И вы начали аргументировать, что чем толще рантайм и слой абстракций в самом языке, тем больше проблем такие оптимизации делать. С чем я согласен.


Просто уточню, что решение на Rust (раз уж за него зацепились) отставало от 1-го места по очкам менее чем вдвое. И именно в этом контексте я и написал, что в таких условиях решает не язык, а конкретные оптимизации.

По отзывам довольно много приходит питонистов и рубистов, которым надо оптимизировать какой-то нагруженный кусок, а писать на С/С++ боязно. Плюс — хайлоад кап был чисто русский, так что могло быть просто мало народу в русскоязычном комьюнити. Я например узнал о соревновании сильно постфактум.

Что мешало всем остальным языкам «оптимизировать» «свои» «алгоритмы»? Я уж не буду говорить о том, что именно язык прямо и косвенно влияет на возможность оптимизаций. Косвенно через компетенцию автора в данном контексте, а прямо через возможности языка.
Приведу простые примеры. Откуда у человека, который писал на готовом веб-стеке на том же пхп/ноде есть необходимые навыки сетевого программирования?

Здесь не совсем понял, кого вы защищаете, а кому пеняете.


  • Си — КМК всё ясно, это язык, тождественный языку интерфейса системных библиотек. К тому же, до недавнего времени ему по факту не было альтернативы для таких задач.
  • Го — следуя вашей логике, откуда у человека, который писал на готовом net/http, необходимые навыки сетевого программирования?
  • Rust — упомянутые вами средства оптимизации там есть, но их надо применить; было ли это сделано в топовом решении — я не знаю.
  • А вообще в топ-50 попало решение на Perl — что тоже кое о чём говорит.

Или уточните, о чём речь.


Как вы будите оптимизировать аллокации на языке с ГЦ?

Эээ… пулинг и буферы, как и без ГЦ? Если конечно стек на этом языке такое позволяет.


А с неуправляемым ГЦ?

Это как? ГЦ который сам в истерике выделяет и удаляет память? :)

Проблема в том, какое определённое мнение ваши реплики, а также Crandel, сформируют о самом сообществе Rust у присутствующих здесь. СпокойнЕе надо быть. Тем более, что ребята из мэйл.ру не встали в позу, а спокойно, как адекватные люди, сказали "Упс, да, ошибочка".

Так вот, это сообщество нашло эту кажется простую ошибку спустя только 2 года. Выходит, проблема была и до статьи, что только добавляет очков к Go.

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

Это вы как-то палку перегибаете. Если одна статья с бенчмарками, пусть и от Мэйл.Ру, способна нанести серьёзный вред сообществу — я уж и не знаю.

Мне кажется, вопрос не в фанатизме, а в публичности — когда публичные действия "лица" некоммерческой организации противоречат одной из целей этой организации. Просто сидеть и контрибьютить в ядро можно и с Windows, если уж так припёрло. Это как актриса публично заявляет, что поддерживает общества по защите животных — но при этом ходит в натуральной норковой шубке.

Information

Rating
Does not participate
Location
Украина
Registered
Activity