Эта история начинается с того, что я попытался переустановить Windows на ноутбуке, доставшемся мне вот с такой наклейкой Certificate of Authenticity (COA): часть символов серийника видны хорошо, остальные – в большей или меньшей степени угадываются; но несколько попыток ввести серийник «на глаз» успехом не увенчались. Пришлось углубляться в вопрос подробнее.
Пользователь
Влияет ли язык на мышление? или: «У вас на юго-восточной ноге сидит муравей»
Я давно лелеял мечту изучать лингвистику в Кембриджском университете. Каждое лето он проводит среди абитуриентов конкурс эссе на лингвистические темы; и профессор, отвечающий за связь факультета лингвистики с абитуриентами, посоветовал мне ради подготовки к поступлению поучаствовать вне конкурса. Летом 2016 тема эссе звучала так: «Часто утверждают, что наш язык влияет на наше мышление. Как это утверждение можно трактовать? Оцените его, приводя примеры из межъязыковых сравнений и/или психолингвистических экспериментов.» Осенью того года я получил от профессора крайне лестную оценку моего эссе; и тем не менее, в Университет меня не приняли. Этим летом я решил сдуть с того эссе виртуальную пыль, и перевести его на русский.
Вопрос «Влияет ли язык на мышление?» давно волнует умы, и немало статей озаглавлено этим вопросом. Связь между языком и мышлением была отмечена уже два века назад, и успела укорениться в массовом сознании: например, распространён миф о том, что у эскимосов необычно богатый набор слов для обозначения видов снега. Аргумент про «эскимосские названия снега» применяют двояко: указывая либо на то, что люди вырабатывают более богатый набор обозначений для того, с чем чаще имеют дело; либо на то, что более богатый словарный запас позволяет выражать более тонкие смысловые различия, незаметные носителю другого языка: «Мы, европейцы, так же неспособны различать виды снега, как дальтоники неспособны различать цвета.»
«Языковой дальтонизм», т.е. отсутствие в некоторых языках названий для некоторых цветов, интригует исследователей уже дольше века. Начиная с середины 20 в. проводились эксперименты, доказавшие, что людям легче различить два цвета, если в их языке эти цвета называются по-разному. Например, народу химба, живущему в Намибии, сложнее, чем нам, отличить синий от зелёного, зато проще отличить dumbu — так на языке химба называются жёлтый и бледно-зелёный цвета — от burou, соответствующего тёмно-зелёным, синим и фиолетовым оттенкам.
Щ — самая упорная из православных букв
Амбициозный проект Луначарского — далеко не первое предложение по упрощению русской орфографии, оставшееся нереализованным.
История славянских шипящих: почему мы пишем жи-ши через И?
Орфография многих живых языков отражает давно исчезнувшие вещи: например, написание английского слова knight указывает на то, что когда-то в 14 в. оно произносилось «книхт». В русской орфографии тоже полно «доисторических окаменелостей»; и для того, чтобы не зубрить, а понимать орфографические правила — нужно разбираться, откуда эти правила взялись. Готового обзора истории шипящих я не нашёл, так что взялся составить его сам. Особенно интригует природа буквы Щ — самой необычной в нашем алфавите.
Имена медведя и пелевинская мистификация
Медведи — самые крупные из наземных хищников. Неудивительно, что с древнейших времён у людей были суеверия по поводу названия этого зверя; такие суеверия будоражат фантазию писателей и в наши дни. И для Пелевина, и для Манро художественная сторона повествования важнее лингвистической достоверности; но если прочие этимологические «прозрения» пелевинского героя («...самое глубокое из моих прозрений было следующим – я истолковал «Петро-» [в слове Петродворец] не как имя Петра Первого, а как указание на связь с нефтяным бизнесом, от слова petrol» и т.п.) сложно воспринять всерьёз, то толкование «берлога — это логово бер-а» завладело изрядным числом умов, и многократно всплывало в комментариях на Хабре — причём не как хлёсткая шутка талантливого писателя, а как объяснение происхождения слова берлога на полном серьёзе.
Самая совершенная китайская пишущая машинка
На Хабре уже были статьи об истории набора на китайском: в эпоху механической печати не обойтись было без устройств с тысячами отдельных литер и вместо клавиатуры — указателем, перемещающимся в двух измерениях. Лишь в 1980-х, на закате машинописи, развитие микроэлектроники позволило создать китайскую пишущую машинку с привычной европейцу клавиатурой. Хотя посмотрите-ка на эту клавиатуру пристальнее: латинские буквы на клавишах заметно искажены, особенно N и M. Это легендарная китайская небрежность, или же искажённые формы букв несут глубокий смысл?
Об украинских и русских гласных
Одно из самых заметных отличий украинского языка от русского — гласный [і] на месте дореволюционного ятя и в тех словах, где в русском [о]: двір, дім, сіль, радість и т. п. Это отличие настолько характерно, что стереотипным «плохим украинским» в юморесках стал русский с заменой [о] на [і]: «кровосісі» и т. п. При этом в других, внешне похожих словах — русскому [о] соответствует [о] и в украинском: кров, рот, сон, голос, ворон и т. п. В чём же разница между этими двумя группами слов? Статья «Икавизм» в русской Википедии предельно лаконична: «переход звуков [ě] (ять), [o], [е], [у], при их нахождении в закрытом слоге, в звук [i]» — хотя и во второй группе слоги закрытые.
Считается, что в праславянском языке было четыре кратких гласных [е о ъ ь], пять долгих [а и у ы ѣ] и действовал закон открытого слога, в соответствии с которым все слоги обязаны завершаться гласным: *дво.ръ, *до.мъ, *со.ль, *ра.до.сть, *кръ.вь, *ръ.тъ, *съ.нъ, *го͡л.съ, *во͡р.нъ. Около 7 в. дифтонги [о͡л] и [о͡р] распались, и закон открытого слога потребовал исправить ситуацию: в древнерусском получились го.ло.съ и во.ро.нъ, в западно- и южнославянских языках (включая церковнославянский) — гла.съ и вра.нъ. Затем в 11–13 вв. произошло падение редуцированных: нечётные [ъ] и [ь], считая от конца слова, исчезли, а чётные понизились до [о] и [е] соответственно: сон, во‿сне ← *съ2нъ1, *въ2‿съ1нѣ. Беглый [о], получившийся из древнерусского [ъ], соответствует [о] и в украинском. Дополнительный признак такого [о] — соответствие [e] в западнославянских языках, например в чешском: krev, ret, sen. В отдельных случаях этот гласный небеглый в русском, но беглый в других языках: в крови, v krvi [ˈfkr̩.vɪ] ← *въ кръве. Второй случай, когда русскому [о] соответствует [о] и в украинском, — полногласные сочетания оро и оло, дополнительный признак которых — неполногласные соответствия в других языках: голос ворон, hlas vran ← *голсъ ворнъ.
Айс, цвай, трю: история 3 дифтонгов
Начало счёта по-немецки — eins, zwei, drei — знают даже те, кто никогда немецкий не учил. Запоминанию этих числительных способствует и то, что все три рифмуются. Тем больший сюрприз ждёт приехавших в Швейцарию, потому что в швейцарском немецком рифмы нет. Представление о провинциальном диалекте как о результате «искажения» столичного языка соседством с иноязычными областями — не позволяет объяснить, каким образом такая броская рифма могла бы потеряться.
Эмодзи 18 века
Этот текст отсканирован из книжки Татибана Нанкэи (1795), и его устройство объясняется в статье Шарлотты Юбанкс (2013) на примере заглавия: Mahā prajñā pāramitā hṛdaya sūtra, что на санскрите означает «Великая сутра сердца совершенной мудрости». Китайцы перевели два слова hṛdaya sūtra «сутра сердца» на свой язык как xīn jīng, а остальные слова заглавия транслитерировали: из mahā «великий» получилось móhē «тереть брань», из prajñā «мудрость» — bōrě «ось если», и т.д. Японцы читают китайское название как maka hannya haramita shin gyō, и в варианте «для неграмотных» записали его как «мишень (ma) — сторона (ka) — демон (hannya) — беременная (harami) — поле (ta) — древесина (shin) — храм (gyō)». Получающаяся «эмодзи-сутра» осмысленна настолько, насколько может быть осмысленной двойная транслитерация санскритского текста через китайский язык.
Откуда взялся 'do' в вопросах и отрицаниях?
В июне на Хабре было сразу несколько интересных статей на лингвистические темы, и одну дискуссию из комментариев мне хочется вынести в отдельную статью: удивительная и, по-видимому, уникальная особенность английского — то, что в вопросах и отрицаниях обязательно должен быть вспомогательный глагол, даже когда утвердительные предложения обходятся без него. Откуда же английская грамматика почерпнула эту свою особенность?
Важно понимать, что вспомогательные глаголы для образования сложных времён — это не что-то особенное, и у нас они тоже есть: рус. буд.вр. он будет писать письмо, укр. дпр.вр. він був написав листа. Более того: колебания между использованием и неиспользованием вспомогательного глагола русскому языку тоже знакомы: в древнерусском было два простых прошедших времени (аорист, невѣжѧ писа недума каза "незнающий написал, недумающий показал", и имперфект, ѡни моляхуся аз же глумляхъся "они молились, а я шутил") и впридачу сложное, перфект: еси приходиле в русь "ты приходил в Русь", зарубати посылали есмо "мы посылали зарубать". Простые прошедшие времена исчезли из всех славянских языков, кроме болгарского и македонского; с перфектом же произошла более интересная история...
Быстрое сравнение double
Положительные double сравнивать очень просто: нормализация гарантирует нам, что из чисел с разной экспонентой больше то, чья экспонента больше, а из чисел с равной экспонентой больше то, чья мантисса больше. Стандарт IEEE 754 заботливо поместил экспоненту в старшие биты, так что положительные double можно сравнивать просто как int64_t.
С отрицательными числами немного сложнее: они хранятся в прямом коде, тогда как int64_t — в дополнительном. Это значит, что для использования целочисленного сравнения младшие 63 бита double необходимо инвертировать (при этом получится -0. < +0., что не соответствует стандарту, но на практике не представляет проблемы). Явная проверка старшего бита и условный переход уничтожили бы всю выгоду от перехода к целочисленному сравнению; но есть способ проще!
inline int64_t to_int64(double x) {
int64_t a = *(int64_t*)&x;
uint64_t mask = (uint64_t)(a >> 63) >> 1;
return a ^ mask;
}
inline bool is_smaller(double x1, double x2) {
return to_int64(x1) < to_int64(x2);
}
a>>63
заполняет все 64 бита копиями знакового бита, и затем >>1
обнуляет старший бит.Генератор неслучайных чисел
import java.util.Random;
class WTF {
public static void main(String[] args) {
Random r = new Random(76880392499L<<11);
String alphabet = " abcdefghijklmnopqrstuvwxyz";
int n;
while ((n = r.nextInt(alphabet.length())) > 0)
System.out.print(alphabet.charAt(n));
}
}
Можете проверить; вывод кажется совсем не случайным. Как же так вышло?
Прежде всего: какой шанс, что из всех последовательностей латинских букв напечатается именно эта? Сгенерировано 10 случайных чисел, каждое выбиралось из 27 вариантов, значит всего вариантов было . Если считать, что все варианты равновероятны, то нам выпал один шанс из двухсот миллионов миллионов! Ух!
Загадочные субтитры на CNN
Как такое могло получиться? (По состоянию на 1/12/2020, субтитры на YouTube так и не исправлены.)
Stenotype
Американские стенографисты уже больше сотни лет как используют специальные устройства с минимальной 22-клавишной клавиатурой — по две клавиши под каждый палец, чтобы минимизировать движения кистей:
Сто лет назад стенотайп был вариантом печатной машинки, и каждая клавиша оставляла оттиск на бумаге. Каретки не было: после каждого «аккорда» из одной или нескольких одновременно нажатых клавиш, бумага проматывалась на одну строчку вниз. Оттиск каждой литеры приходился всегда на одно и то же место в строке. Клавиши P, R, S, T присутствуют в двух экземплярах каждая — под левой и под правой рукой.
Windows 95 на двух флоппиках
Общий подход я уже описывал в комментариях: создаётся RAMDRIVE, и на него разворачивается двухтомный SFX-архив. Но есть много тонкостей:
- Как видно на видео выше, распакованная папка Windows у меня занимает 6.2 МБ. Я взял за основу список файлов Micro95, и дополнительно удалил файлы, оказавшиеся необязательными — например, шрифты и драйвер
dosnet.vxd
. Кроме того,vmm32.vxd
я распаковал, и удалил бывшие внутри него необязательные драйвера.
QR-художество
На хабре уже обсуждалось устройство QR-кодов и украшение их произвольными рисунками, но дизайнерская мысль до сих пор работала только в двух основных направлениях: замена квадратных модулей на более интересные формы, либо замена части кода рисунком. Такие художества возможны благодаря тому, что блоки данных в QR-коде дополняются кодами Рида-Соломона, позволяющими восстановить до 30% искажённых байтов. Основываясь на этом, дизайнеры QR-кодов давно уже наловчились заменять участок, занимающий до 30% площади кода, какой-нибудь картинкой. Я же решил испробовать другой подход — художественно искажать в QR-коде отдельные биты в целях получения интересного изображения. Например, в этом коде инвертированы лишь 50 модулей из 841.
Откуда в Windows взялись функции BEAR, BUNNY и PIGLET?
BEAR35
, BUNNY73
и PIGLET12
. Откуда взялись эти дурацкие имена?Почему в EBCDIC буквы идут не подряд?
Стандарт ASCII был принят в 1963, и сейчас вряд ли кто-нибудь использует кодировку, первые 128 символов которой отличались бы от ASCII. Тем не менее, до конца прошлого века активно использовалась EBCDIC — стандартная кодировка для мейнфреймов IBM и их советских клонов ЕС ЭВМ. EBCDIC остаётся основной кодировкой в z/OS — стандартной ОС для современных мейнфреймов IBM Z.
То, что сразу бросается в глаза при взгляде на EBCDIC — то, что буквы идут не подряд: между I и J и между R и S остались неиспользованные коды (на ЕС ЭВМ по этим промежуткам распределили символы кириллицы). Кому могло придти в голову кодировать буквы с неравными пропусками между соседними буквами?
Вторая жизнь Virtual Floppy Drive
Перенос файлов через дискету был медленным и шумным, и моему восторгу не было предела, когда я нашёл драйвер Virtual Floppy Drive, позволяющий создать «виртуальный флопповод» и подключить его в VM как обычный. К сожалению, интерес автора к своему проекту угас в 2005, а в 2010 его сайт и емейл перестали существовать. С тех пор в мире Windows успело произойти много перемен:
- Повсеместно стала использоваться 64-битная ОС, в которую невозможно загрузить 32-битный драйвер, скомпилированный в 2005;
- Windows начиная с Vista SP1 стала требовать для загрузки драйверов либо цифровую подпись, либо муторные манипуляции, требующие перезагрузку системы;
- Проект, написанный в Visual C++ 6, не собирается в современных версиях Visual Studio после автоматической конвертации.
Аутенти(фи?)кация
Теперь я всё чаще, и в т.ч. на Хабре, встречаю слово аутентификация в качестве кальки английского authentication. Английское слово образовано от латинского authenticatus и далее от греческого αὐθεντικός — ни в одном из них нет -фи-, -fi- или -φι-! Более того, братья-славяне пишут автентикация по-болгарски и аутентикација по-сербски.
Слово аутентикация когда-то и по-русски писалось без -фи-. Гугл находит примеры из книг 1927, 1964 и 2002 г.г.:
Сколько инструкций процессора использует компилятор?
mov
. (В общем-то известно, что одних инструкций mov
достаточно, чтобы написать любую программу.)Я решил развить исследование de Vos, взяв в качестве «эталонного кода» компилятор LLVM/Clang. У него сразу несколько преимуществ перед содержимым /usr/bin неназванной версии неназванной ОС:
- С ним удобно работать: это один огромный бинарник, по размеру сопоставимый со всем содержимым /usr/bin среднестатистического линукса;
- Он позволяет сравнить разные ISA: на releases.llvm.org/download.html доступны официальные бинарники для x86, ARM, SPARC, MIPS и PowerPC;
- Он позволяет отследить исторические тренды: официальные бинарники доступны для всех релизов начиная с 2003;
- Наконец, в исследовании компиляторов логично использовать компилятор и в качестве подопытного объекта :-)
Начну со статистики по мартовскому релизу LLVM 10.0:
ISA | Размер бинарника | Размер секции .text | Общее число инструкций | Число разных инструкций |
---|---|---|---|---|
AArch64 | 97 МБ | 74 МБ | 13,814,975 | 195 |
ARMv7A | 101 МБ | 80 МБ | 15,621,010 | 308 |
i386 | 106 МБ | 88 МБ | 20,138,657 | 122 |
PowerPC64LE | 108 МБ | 89 МБ | 17,208,502 | 288 |
SPARCv9 | 129 МБ | 105 МБ | 19,993,362 | 122 |
x86_64 | 107 МБ | 87 МБ | 15,281,299 | 203 |
А вот распределение по числу инструкций: