Я в интернете

РСС    Джейсон-фид

Есть автоматические трансляции в Тумблер и Же-же. Если не работает, напишите мне: ilyabirman@ilyabirman.ru.

2

Избранное

Шифт+Энтер на Айфоне

Сначала историческая справка.

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

Первобытные текстовые редакторы вставляли эти же два управляющих символа в текст при нажатии на кнопку Энтер. По-английски они называются carriage return и line feed. Последовательность символов CR, LF (она же \r\n) означала начало следующей строки в ДОСе и означает в его наследнице Винде. В Юниксе же решили, что глупо ставить два символа для переноса строки и ограничились одним LF (он же \n). С тех пор эти два способа закончить строку дерутся и создают кучу проблем.

Так или иначе, ещё в 20 веке придумали, что вообще-то на компьютере текст сам переносится на следующую строку когда места перестаёт хватать, и никаких специальных символов для этого не надо.

С тех пор Энтер в текстовых редакторах не просто переходит на следующую строку, а начинает новый абзац и отделяет его отступом. Чтобы просто перейти на следующую строку, не начиная новый абзац и не делая отступа, как на печатной машинке, нужно жать Шифт+Энтер. Аналогично Шифт+Энтер позволяет перейти на следующую строку в том же элементе списка, не переходя к следующему, ну и вообще в любом логическом блоке текста.

А теперь к сути заметки.

Мне всю жизнь не хватало такой фичи на Айфоне. Хочется, бывало, в ту же тудушку добавить текста с новой строки или ещё что-то подобное сделать.

И тут я на днях попробовал нажать Шифт+Энтер на Айфоне — и он сработал! Ровно так, как всю жизнь работал на компьютере. Теперь я думаю, что он так наверняка работал с первого Айфона, но мне никогда не приходило в голову попробовать, и я не могу понять почему. Я просто всю жизнь был уверен, что на Айфоне это сделать невозможно.

Сейчас анализируя это я думаю, что есть некое общее представление о том, что на Айфоне нет клавиш модификаторов типа Альт и Комманд, а кнопка Шифт — это не совсем модификатор, а как бы просто «вкладка» такая в клавиатуре, как и 123. Я ж не могу на Айфоне с Шифтом выделять текст или ещё что-то подобное делать, поэтому и Шифт-Энтер попробовать просто в голову не приходило. А зря!

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

Мы должны вести пользователей создавать личный кабинет

У меня очередной примерчик в коллекции:

Мы посмотрели статистику и оказалось, что пользователи, у которых есть личный кабинет, покупают у нас чаще. Поэтому мы должны вести всех пользователей создавать личный кабинет.

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

Секс вокруг нас

В «Скучном секс-блоге» недавно был пост «Мир глазами мужчины». Там женщина сделалась мужчиной и офигела от того, что теперь всюду видит секс.

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

Для меня это звучит очень странно. Ну да, секс повсюду, ты думаешь про секс всё время. Как говорится, «а минусы будут?» Это не ощущается как что-то обременительное и тягостное. Это совершенно естественное и органичное ощущение, оно не мешает жить, оно и есть жизнь. Это же реальность: секс действительно вокруг нас, его очень много, а как же может быть ещё? Это же само собой.

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

Бывает, конечно, что где-то слишком шумно или слишком жарко, но как можно захотеть оглохнуть или не чувствовать температуры? Точно так же, как ты всегда чувствуешь, голодный ты или сытый, холодно тебе или тепло, устал ли ты, хочешь ли ты потянуться; так же как ты видишь, слышишь, чувствуешь запахи — так же ты чувствуешь и весь секс вокруг. Как можно хотеть лишиться одного из чувств? Звучит как безумие.

О непостоянстве убеждений

Люди с непостоянными убеждениями придумали оправдание, что изменения — это признак их роста. Они с гордостью говорят: «с возрастом я стал думать иначе» или даже «я поумнел». Если обратить их внимание на непоследовательность, они скажут, что только глупцы никогда не меняют взгядов.

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

Иногда к изменениям убеждений приводят значительные жизненные события: переезд в другую страну, рождение детей, пережитая тяжёлая болезнь. Такое кажется уважительной причиной для перемен, но на самом деле ещё хуже: получается, твои «убеждения» никакие не убеждения, а просто следствие обстоятельств, с которыми тебя столкнула жизни. Был ты убеждённым капиталистом, но потом твой бизнес прогорел и ты стал убеждённым социалистом? Так ничего не изменилось: ты как защищал собственные интересы подвернувшимся словом, так и защищаешь, а убеждений у тебя как не было, так и нет.

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

А то выходит, будто можно иметь два разных мнения по одному вопросу. Можно-то можно, но не удивляйся, что с тобой не хочется иметь серьёзных дел. Мало ли, что тебе там надует в голову ещё через год.

Вайбкодинг и качество

Ещё в прошлом году вайбкодинг мне казался лишь игрушкой. Круто, конечно, что можно что-то там сказать компьютеру, и он сделает. Но результат будет держаться на соплях и сойдёт разве что как прототип. Чтобы сделать качественную, надёжную вещь, нужно держать весь код под контролем. Можно писать его с нейросетями, но нужно понимать, из каких абстракций он состоит, как они связаны, какие события как обрабатываются, что где хранится и так далее.

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

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

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

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

Проектирование дизайна как создание объяснения

Прошу своих студентов придумать, как должна выглядеть и работать следующая версия их продукта. Они пишут, мол, там будет то и сё, и надо будет учесть это и это. Кажется, они думают, что они всё понимают, а я всё никак не удовлетворюсь их ответами. Периодически даже звучат слова вроде «давай мы сделаем прототип или даже навайбкодим тебе». А я говорю, да погодите, вы мне объясните сперва!

Я верю в идею «кто ясно мыслит, тот ясно излагает», поэтому если вы правда способны сделать прототип, то значит вы понимаете, как всё должно работать, и можете это рассказать. По моему опыту, многие дизайнеры даже не осознают того, что у них в голове нет целостной картины продукта.

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

В общем, наша переписка продолжается какое-то время. Они уже пишут подробный текст, но им всё ещё моя просьба кажется удивительной: «Неужели тебе правда это удобнее, чем макет или прототип? На макете же сразу видно, где что!»

Я:

Какой толк от прототипа? Ведь из прототипа я ничего не пойму. Я буду видеть, что что-то как-то сработало, но я не увижу внутренних причин.

У меня всю жизнь так было, я терпеть не мог прототипы, потому что я с ними как слепой. Как мне увидеть и осмыслить саму систему, а не отдельные её случайные проявления, до которых я докликал? За прототипом очень легко спрятать, что у вас ничего не продумано.

После прочтения Дойча я понимаю, почему так: прототип — не объяснение. Что толку физику от результатов опыта, если у него нет объяснительной теории, которую эти опыты подтверждают или опровергают? Это же просто рандомные факты, вызывающие лишь недоумение. Чтобы понимать, почему они такие, мне нужно открыть, то есть придумать закон, который бы их объяснил.

Но если мне самому нужно придумывать закон, глядя на эффекты его воплощения в прототипе, то в чём тогда была работа дизайнеров? Я ж как раз изначально попросил их придумать этот закон! А в итоге вынужден его придумывать я. Если вы его реально придумали, так просто расскажите. А если у вас только прототип, то вы его, скорее всего, просто не придумали.

Это всё снова показывает, насколько качественное проектирование близко к придумываю законов физики.

Программа при запуске хочет, чтобы я открыл файл

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

Это, как и кнопка «наверх» внизу страницы и кнопка «На главную» на пустом экране — тоже пример того, когда мне протягивают костыль, а я не хромой. Завёл тег «медвежья услуга» по этому поводу.

Во-первых, я сам решу, открывать мне файл или нет. Может, я зашёл просто версию посмотреть или обновление установить? Или я звпустил программу впрок, но прямо сейчас не собираюсь ничего с ней делать. Просто не лезь со своим диалогом и не мешай мне пользоваться компьютером!

Во-вторых, даже если я и собираюсь открыть файл, ну не через диалог открытия файла же я это буду делать! Это самый неудобный способ открыть файл в мире. Файл почти наверняка у меня где-то и так под рукой: в письме, в телеге, на рабочем столе, в папке, в веере Downloads в доке. Я его просто оттуда затащу да и всё. Нафиг мне твой диалог сдался вообще?

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

Где и как подписать дверь

 6 мин

Не только содержание, но и расположение подписи несёт информацию о помещении.

Самое очевидное — это подписать посередине двери на уровне глаз. Просто какой-то кабинет, без постоянного потока посетителей:

Если это аудитория в университете или комната в общежитии, то лучше сделать цифры крупнее, ведь люди ищут их именно по номеру:

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

Естественно, у двери может быть текстовая подпись:

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

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

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

Кстати, туалеты вообще удобнее обозначать иконками:

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

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

Если нужен только номер, его можно разместить и над дверью:

Но читать на такой высоте текст уже не очень удобно. Подпись лучше разместить сбоку:

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

Если номер нужен, но используется редко, его можно снова поставить на косяк:

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

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

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

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

Импликация, следствие и условия

 4 мин

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

Импликация — это логическая операция вида «A → B». Она истинна во всех случаях кроме одного: когда A истинно, а B ложно. Можно оценить по таблице истинности:

A B A → B
0 0 1
0 1 1
1 0 0
1 1 1

То же самое можно сформулировать как «из истины следует истина, а из лжи — что угодно».

Кажется, что это простая штука, ведь в жизни мы легко понимаем выражения типа «Если A, то B» или «Из A следует B». Но если сказать, что «из 2×2=4 следует что Волга впадает в Каспийское море» (V), большинство воспротивится этому. Почему, ведь с точки зрения логики это верное утверждение?

Дело тут в том, что мы не интерпретируем фразу V буквально. Мы видим, что в общем случае из математического равенства не следует географический вывод. То есть мы подсознательно обобщаем V, превращаем в шаблон, и тогда импликация разрушается. Мы понимаем, что имея лишь «2×2=4» и не зная ничего про Волгу, невозможно сделать вывод о том, куда она впадает. Но импликация означает истинность конкретного этого высказывания, а не то, что высказывание сохранит истинность при обобщении.

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

Высказывания типа «Если A, то B» нас интересуют как способ выводить истинность B из истинности A или наоборот, то есть только тогда, когда мы не знаем одно из них. А для этого нам нужно вскрыть содержательную связь между A и B, а не просто значения их истинности. Тут-то нам и нужны шаблоны, да такие, что мы уже заранее знаем, что импликация там истинна!

Предположим, мы знаем, что «у каждого голландца есть велосипед» (K). Заметьте, что это уже утверждение, содержащее импликацию («если человек голландец, то у него есть велосипед»), и мы уже договорились, что оно истинно. Вот теперь если мы узнаем, что Фёдор голландец, мы сделаем вывод о том, что у него есть велосипед. Импликация помогла сделать этот вывод только потому, что мы 1) уже знали, что сама она истинна, и вдобавок 2) она имела форму шаблона, в который можно было подставить Фёдора. От истинности же импликации V из начала заметки нет никакого проку. Поэтому с такими видами совершенно верных высказываний мы никогда не имеем дела. Они нам кажутся настолько пустыми, что мы не готовы даже пытаться оценивать их истинность.

Один из комментаторов у Никиты написал, мол, как же импликации нет в языках программирования, когда там есть if (a) b? Но что значит? В известных мне языках программирования это даже не является выражением, но если бы являлось, каким было бы его значение? Иными словами, что бы нам дал вывод print (if (a) b)? Конечно же true! Ведь в этом буквально состоит работа языка программирования: обеспечить b, когда истинно a. Если он этого не делает, то зачем такой язык программирования нужен? Но в то же время, если a ложно, то глядя на эту строчку мы никак не сделаем вывод о том, произойдёт ли b. Может, какая-то другая часть кода обеспечит b. Строчка if (a) b никак не способна предотвратить b.

Получается какая-то эзотерика, и только потому, что никто никогда не рассматривает if (a) b как логическое выражение и не пытается оценить его истинность. Всех интересует только логическое выражение a по отдельности, потому что от его истинности зависит, может ли быть уверены в том, что произойдёт b.

Импликация в языках программирования была бы, если бы можно было написать if (a→b) c, то есть «если из a следует b, обеспечь c». Но нафиг это надо? Как мы уже выяснили, когда значения a и b уже известны, значение истинности их импликации не несёт никакой пользы и почти никакого смысла.

Теорема о тормозах

Поговорим о ситуациях, когда компьютер тормозит.

Под тормозами понимается медлительность, мешающая свободному взаимодействию и тем самым вызывающая фрустрацию и раздражение. Если компьютер скачивает пять гигабайт данных, компилирует сложный проект или рендерит видео, это занимает ощутимое время, но это не тормоза: мы дали компьютеру задачу, и он работает, выполняет. Теперь допустим, что видео рендерилось час, потом отобразился статус «Завершено», а через секунду готовый файл отобразился на рабочем столе. Первый час компьютер не тормозил, но следующую секунду — тормозил.

Теорема: все тормоза являются ошибками и исправимы.

Технически даже своевременное отображение статуса или реакции не действие пользователя — это такая же «работа», как и рендеринг видео. Однако такая работа должна быть выполнена за время, которое человек не способен ощутить. Будем называть это «мгновенно».

Примеры тормозов в современно софте:

  • при запуске программы нельзя сразу же начать ей пользоваться, а нужно ждать загрузки;
  • после загрузки часть интерфейса дорисовывается на глазах у пользователя;
  • при нажатии на кнопку нет мгновенной реакции;
  • при вводе с клавиатуры символы появляются не мгновенно;
  • при прокрутке страница едет не плавно или с отставанием от пользователя;
  • при прокрутке часть содержимого догружается на глазах у пользователя, а не приезжает уже готовым из-за края окна;
  • при изменении размеров окна разные части интерфейса перерисовываются на глазах у пользователя с разной скоростью или в несколько «прыжков»;
  • при перетаскивании объекта программа понимает, что может «принять» его, не мгновенно;
  • после открытия меню, на глазах у пользователя в нём добавляются пункты или меняется их порядок;
  • разные части интерфейса реагируют на действия пользователя через разное время.

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

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

Таким образом, тормоза нельзя списать на слабое железо; это слабость исключительно её автора.

Ранее Ctrl + ↓