Pawel
Питон, как мне кажется, на базовом уровне проще, чем Паскаль
Наглядный пример этой "простоты" (за которую хочестя убить) 1) if condition: try: cursor = db.cursor() updateData(cursor) finally: cursor.close() 2) if condition: with db.cursor() as cursor: updateData(cursor) Можно написать и так и так, и никто вас не остановит до тех пор, покуда не будет condition == True. Кто-нибудь скажет нубу, что для курсора не определены методы __enter__ и __exit__? - интерпретатор во время выполнения и только тогда, когда condition будет True! И скажет пользователю программы, отказавшись сохранить его данные.
🎉
Нубских вопросов накопилось. Вот посмотрел доклад, вот этот https://youtu.be/me5iyiheOC8 и возникли вопросы, есть net/http там разве не реализовано грэйсфул шутдаун?
Oleh
Где то смотрел статейку как сделать грейсфул шатдаун
Oleh
Погугли найдешь
Daniel
Нубских вопросов накопилось. Вот посмотрел доклад, вот этот https://youtu.be/me5iyiheOC8 и возникли вопросы, есть net/http там разве не реализовано грэйсфул шутдаун?
нет, не реализовано. в принципе, ренализовать его не сложно самому. просто не принимаешь новых соединений, и, когда счетчик обработчиков падает до 0 - выходишь. вот только в современном мире graceful не очень полезен
🎉
Спасибо.
Артемий
ответ в одной гифке: https://qph.ec.quoracdn.net/main-qimg-dd2dc3bc72b058b85774ee804a521165
интересно, можно было бы же сделать без генериков, просто добавив возможность в интерфейсы включать функции операторы, что типа int поддерживает операторы сложения сравнения, а дальше написать функцию min которая принимает интерфейс типа у которого определен оператор <. Как в с++ можно такие операторы определять
Daniel
и это самое мерзкое, что есть в c++
Daniel
там много гадости, но эта - самая самая
Артемий
ну можно запретить переопределение операторов, а только использование тех которые уже встроены в базовые типы, чтобы указывать их в интерфейсах
Alexander
А что такого мерзкого в перегрузке операторов?
Daniel
чтобы читать код на c++ надо знать наизусть весь проект и все либы, в нем использующиеся. потому, что иначе сюрприз может поджидать за каждым кустом
Артемий
А что такого мерзкого в перегрузке операторов?
я так понимаю неявность, что ты никогда не знаешь что скрывается за простым + пока в код не посмотришь
Daniel
есть такой оператор <<. его принято определять для организации вывода, конкатенации и еще всякого. так вот, несклько раз я видел в нем развесистую логику.
Alexander
я так понимаю неявность, что ты никогда не знаешь что скрывается за простым + пока в код не посмотришь
Есть такое, но не так уж и страшно. Просто не надо делать нелогичные вещи. Так то сложение/умножение матриц и векторов или, например, комплексных чисел, очень неплохо делать перегрузкой операторов.
Артемий
векторное или скалярное произведение v1*v2?
Daniel
нет никакой необходимости делать это перегрузкой. обыкновенная функция не хуже.
Мерль
нет никакой необходимости делать это перегрузкой. обыкновенная функция не хуже.
Это пока у тебя нет сложных конструкций Иначе начинается адок
Alexander
векторное или скалярное произведение v1*v2?
Очевидно, зависит от типов переменных.
Артемий
но опять же, хрен с ней с перегрузкой, я говорю что много кейсов просто покрывается первоначальным определением что тип умеет складываться делится сравниваться и т.д., Не обязательно при этом добавлять перегрузки. И наверно даже не обязательно разрешать опередление таких операторов для сложных типов
Мерль
Другой момент если у тебя перегружен оператор для двух разных типов, вот тогда начинается АДЪ
Daniel
Это пока у тебя нет сложных конструкций Иначе начинается адок
где это он начинается? оператор - та же функция, но ты 1. должен помнить, какая именно вызовется для этой пары аргументов. 2. компилятор не проверит тебе типы
Мерль
где это он начинается? оператор - та же функция, но ты 1. должен помнить, какая именно вызовется для этой пары аргументов. 2. компилятор не проверит тебе типы
Это плохо только для cpp В том же русте и хаскеле тебе и типы проверят, и не дадут строку с флоатом сложить
Alexander
Это проблема самой возможности перегрузки функций с разными параметрами (которой в Го нет). Хотя перегрузка именно операторов немного путаницы тоже добавляет, конечно.
Alexander
int min(int a, int b) float min(float a, float b)
Мерль
где это он начинается? оператор - та же функция, но ты 1. должен помнить, какая именно вызовется для этой пары аргументов. 2. компилятор не проверит тебе типы
А начинается ад когда у тебя определение функции занимает пару экранов вместо строки(это у меня реальный кейс на го был)
Мерль
И потом ты пытаешься найти ошибку в математике
.
в Го же вполне возможно реализовать Stack & Queue?
Мерль
И тогда начинаешь жалеть что написал не на cpp
.
И правильно ли я понимаю что делается это через систему типов и структур
Мерль
в Го же вполне возможно реализовать Stack & Queue?
Либо пиши велосипед, либо через пустые интерфейсы Стек хорошо через слайс, очередь — в зависимости от конкретного случая
Daniel
при чем тут интерфейс?
Артемий
типа type A interface{}?
func (s * Stack) Push(item interface{}) {}
.
Так и думал
.
Спасибо
Daniel
не надо так делать
Daniel
совсем не надо
.
Ну можно не через интерфейс
.
типа Stack с конкретным типом
Мерль
не вижу никакого ада тут.
Ну это потому что не нужно было видимо ( Я имел счастье писать более менее сложную математику и cpp, питончеге и go Из этой тройки go хуже всего подходит для такой эквилибристики
Мерль
По крайней мере по моему опыту
Anonymous
Ох уж эти гоферы. Перегрузка видете ли усложняет, а передавать в параметры функций интерфейсы - это норм!..
Артемий
Daniel
стек в программе не нужен обычно универсальный. нужен под конкретный тип. под него и пишите
Артемий
ну речь наверно не про конкретно стек, а про нечто более сложное, что не хочется под каждый тип дублировать
Артемий
вот например популярная вроде либа https://godoc.org/github.com/oleiade/lane через interface сделана
Daniel
да полно их, сделанных через интерфейс. но мы же понимаем, что, используя пустой интерфейс мы выносим проверку типов и связанных с ними ошибок в рантайм.
Мерль
На самом деле чтобы именно изучать алгоритмы, то писать свои велосипеды — это даже правильно и полезно, имхо
Daniel
Это пожалуй единственный случай когда golang вынуждает писать совершенно неподдерживаемый код
не могу поддержать разговор, не писал по-настоящему сложной математики на go. операции с числами big.Int, например, слегка коряво смотрятся. видимо об этом речь. но вот чтобы этот код был неподдерживаемый - нет, это не так.
Артемий
вот захочешь ты себе какой-нибудь mq кеш, который за 5 мин нормально наверно не напишешь, не будешь же ты под каждый тип сидеть дублировать. Либо придется через интерфейсы, либо какую-то обертку чтобы он внутри хранил только какие-то id объектов, и говорил тебе когда удалять их, а ты ему говорил когда добавил id и когда считал id, а сам объекты по id в мэпе хранить. Тот еще изврат
Roman
Кстати, тут в обсуждениях задевалась тема мат. вычислений на го , мол язык с этим плохо справляется , кто-нибудь может сказать почему ?
Daniel
никогда мне не нужен будет иниверсальный кеш.
Daniel
Кстати, тут в обсуждениях задевалась тема мат. вычислений на го , мол язык с этим плохо справляется , кто-нибудь может сказать почему ?
длинные вычисления без вызовов функций и операций ввода-вывода мешают шедулеру равномерно распределять время между горутинами
Мерль
не могу поддержать разговор, не писал по-настоящему сложной математики на go. операции с числами big.Int, например, слегка коряво смотрятся. видимо об этом речь. но вот чтобы этот код был неподдерживаемый - нет, это не так.
Неа, как раз big int — это не слишком страшно, в тех же пакетах криптографиии в стандартной библиотеке полюбопытствуйте, там по божески Самое страшное начинается когда нужна линейная алгебра сложнее "перемножить три матрицы"
Daniel
ну там же и сама математика не простая
Daniel
синтаксического сахара не хватает, я так понял
Roman
А как разряженные матрицы хранятся ? дикт из позиции и значения ?
Daniel
встроенного типа для них нет
Артемий
блин, походу реально сделать кеш, который хранит только айдишники это неплохое решение, типа Push(id) Touch(id) OnRemove(func(id)). А внутри уже любой алгоритм навороченный
Мерль
Кстати, тут в обсуждениях задевалась тема мат. вычислений на го , мол язык с этим плохо справляется , кто-нибудь может сказать почему ?
1. Мало пакетов для математики 2. Нет перегрузки операторов, очень громоздкие нечитаемые выражения 3. Большую часть проверок на размерность и прочее приходится делать в рантайме Скорость как правило не важна, на самом деле
Мерль
ну там же и сама математика не простая
Концептуально — не очень, но по факту там почти под все нужды для этого кейса есть функции в стандартной библиотеке, поэтому получается очень неплохо я бы сказал
Мерль
А как разряженные матрицы хранятся ? дикт из позиции и значения ?
Лучше сделай сам, хотя я видел вроде готовые имплементации для float64
Артемий
а может кто-то сказать, работать с ffmpeg из go через пайпы в линуксе сильно медленнее чем биндинги использовать к сишной либе? если я например запущу несколько процессов ffmpeg и буду в них стримы лить и читать через пайп без запуска процесса на каждый чих
Мерль
Для разреженных матриц лучше из numpy спереть, в доках описаны несколько форматов и кейсы применения, там под конкретный случай лучше выбирать
Мерль
https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html
Roman
что еще для ml юзают помимо python / R ? scala ?
Roman
только не надо что для ml пофиг какой язык, важнее модель )
Мерль
что еще для ml юзают помимо python / R ? scala ?
Если только начинаешь, то я бы взял питон (с R работал мало) так как большая часть курсов и книг заточена под него, + масса хороших библиотек и документации, + гигантское сообщество А потом всё равно выберешь что нужно