Size: a a a

2020 May 16
Блог*
Clippy знает толк в читаемости кода
источник
Блог*
#prog #quotes
источник
Блог*
Переслано от Ender Eyre
программирование и программисты не нужны в программирования, они могут только ныть, жаловаться, нихуя не делать и требовать денег.
источник
2020 May 17
Блог*
#prog #amazingopensource

#  Human injection
#
#  Strings which may cause human to reinterpret worldview

If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.

Из сборника Big list of naughty strings — списка строк, которые приведут к проблемам для софта, который небрежно обрабатывает пользовательский ввод, конкретно здесь
источник
Блог*
#prog #article

Турецкий тест: будет ли ваша программа корректно работать в турецкой локали? Если да, велик шанс, что программа адекватно обрабатывает локали. Почему именно турецкая? Там полно граничных случаев, которые отличают её от английской.

...Правда, для меня главным выводом было "не используйте функции с неявными глобальными зависимостями".

moserware.com/2008/02/does-your-code-pass-turkey-test.html
источник
Блог*
#prog #rust #meme (thanks @repushko)
источник
2020 May 18
Блог*
dereference_pointer_there
Является ли это единственным достоинством нового варианта? Отнюдь.

Оригинальный код собирает промежуточный слайс — в моём варианте собирается только конечный результат (причём память выделяется заранее).
Оригинальный код дважды делает поиск в мапе по итоговым строкам — здесь же поиск осуществляется единожды.
Оригинальный код проходит по всему слайсу sortedIDs — в ржавом варианте обход заканчивается, когда набирается достаточно подходящих строк.
Оригинальный код рассчитывает на то, что в sortedByDateSpottedIDs будет как минимум countIDsNeedToShow строк — в варианте ниже итоговый вектор просто будет содержать меньше paging.limit строк, если их не хватает (это, кстати, можно считать как плюсом, так и минусом, но надо отметить, что нарушение этого ожидания в оригинальном варианте вызовет панику из-за некорректного индекса, а в моём варианте можно постфактум проверить длину возвращённого вектора).

Все эти итераторы в итоге успешно компилируются в единый цикл, так что эффективность в рантайме не страдает. Можно ли применить те же техники оптимизации для Go? Конечно. Вот код, вторично переведённый на другой язык:

func getIDsForTextSearch(
 sortedIDs []string,
 spottedIDsWithDocCount map[string]int,
 paging paging,
) ([]string, int) {
 idsForSearch := make([]string, 0, paging.Limit)
 skip := paging.Offset
 iterated := 0
 total := 0
 
 for _, id := range sortedCallIDs {
   if iterated >= paging.Limit {
     break
   }
   count, spotted := spottedIDsWithDocCount[id]
   if !spotted {
     continue
   }
   if skip > 0 {
     skip--
     continue
   }
   iterated++
   idsForSearch = append(idsForSearch, id)
   total += count
 }
 return idsForSearch, total
}

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

Подведём итоги. У множества задач есть сложность, которую нельзя просто убрать. При дизайне языка программирования можно на него выделить разный бюджет сложности. Создатели Go намеренно этот бюджет урезали, создатели Rust сильно ограничивать не стали (что логично, учитывая, что Rust долго развивался эволюционно, без изначального видения идеального ЯП — и развивается и по сей день). Последствия этих выборов достаточно ожидаемы: в Go сложность задачи размазывается по достаточно объёмному коду, в то время как Rust позволяет использовать сложность языка для того, чтобы получить в итоге относительно простое решение. Кто-то может сказать, что перемещения сложности туда-сюда погоды не делают, и итоговая сложность остаётся той же. Я не могу с этим согласится. Да, Rust относительно сложен (уж точно сложнее Go — и это не хвастовство, а просто констатация факта), но язык, равно как и стандартная библиотека для него, учится один раз, в то время как последствия излишней простоты дизайна языка приходится разгребать в коде постоянно. Лично для меня подобная однократная инвестиция, которая впоследствии пригодится множество раз, видится более разумным выбором — но вы, разумеется, вольны со мной не согласиться.

Спасибо, что пришли на мою лекцию TED
Как мне совершенно правильно сообщил подписчик, iterated можно выкинуть и проверять длину idsForSearch. Впрочем, моя позиция остаётся прежней
источник
Блог*
Внезапно, #math #meme
источник
Блог*
dereference_pointer_there
Внезапно, #math #meme
Немного контекста, в частности, почему именно 1936
источник
Блог*
#prog #rust #meme
источник
Блог*
источник
2020 May 19
Блог*
#quotes
источник
Блог*
Переслано от codingteam@cjr
Minoru
бранч предиктор такой «да не ссы, всё образуется, фигачь в then-ветку!»
источник
Блог*
#prog #rust #article

Как известно, в Rust (почти) нет higher-ranked polymorphism. Тем не менее, иногда его можно эмулировать довольно простым образом.

leshow.github.io/post/cheat_rank_n
источник
2020 May 20
Блог*
#prog #rust #article

Обзор инструментов для верификации кода на Rust.

alastairreid.github.io/rust-verification-tools
источник
Блог*
#meme

Ах да, сегодня ж среда
источник
Блог*
Блеск и нищета #rust
(а ещё это #prog #meme)
источник
Блог*
Подсказка по Self:: 😅
источник
Блог*
#prog #rust

Одним из пунктов снижения размера исполняемого файла скомпилированной программы на Rust является обработка бинаря strip. Недавно это стало возможным делать с помощью cargo. Да, это пока nightly, но это значит, что, скорее всего, на stable попадёт скоро.

(thanks @MikailBag)
источник
Блог*
#prog #rust #go #article

Во многих языках есть отдельный тип данных для символов (я смотрю на тебя, Python). В Rust это char, в Go это rune. Эти типы, казалось бы, одинаковы: оба хранят юникодные символы, оба занимают 32 бита. Тем не менее, в плане диапазона приемлемых значений они заметно отличаются. Чем именно — подробно рассказывается в статье.

christianfscott.com/rust-chars-vs-go-runes
источник