Почему знакомство похоже на систему с неполной информацией, неопределённость удерживает внимание, а алкоголь временно включает unsafe.
Меня зовут Артур Валиев, я разрабатываю EVRT и EVRTCK. В программировании я привык мыслить состояниями, событиями, ограничениями и переходами между ними.
Но однажды возникает вопрос: можно ли тем же способом посмотреть на человеческие отношения?
Не свести любовь к формуле и не написать библиотеку perfect_relationship, а хотя бы разобрать механику происходящего. Почему совершенно незнакомый человек внезапно занимает вычислительные ресурсы нашего мозга? Почему опытный и общительный человек может чувствовать себя скованно на обычном свидании? И в какой момент случайный контакт превращается в привязанность?
Попробуем поговорить об этом на языке Rust.
Дальнейший текст - инженерная метафора, а не научная теория и не руководство по сборке идеального человека, давайте сложно о простом.
Знакомство как система с неполной информацией
При первой встрече мы практически ничего не знаем друг о друге.
Есть внешность, голос, несколько сообщений, профессия, музыкальные предпочтения и набор предположений, значительную часть которых мозг самостоятельно достроил из воздуха.
Можно представить первоначальную оценку контакта так:
interest = possible_reward * success_probability - interaction_cost - perceived_risk - alternative_cost
Под вознаграждением необязательно понимать любовь, секс или семью. Это может быть:
новизна;
внимание;
подтверждение собственной привлекательности;
эмоциональная стимуляция;
уменьшение одиночества;
получение новой информации;
возможность совместного будущего.
Поэтому человек может согласиться на встречу, ещё не испытывая особого интереса к конкретному собеседнику. Иногда цель первой встречи — не получить результат, а просто уменьшить неопределённость.
В терминах Rust вместо готового значения у нас пока только:
let compatibility: Option<Compatibility> = None;
Мы не получили false. Мы пока вообще не получили значения.
Отношения как конечный автомат
У знакомства нет одного бинарного состояния: «любовь» или «не любовь». Связь постепенно проходит через набор этапов.
Упрощённо это можно представить так:
#[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Stage { Unknown, Contact, Interest, Trust, Attachment, Partnership, Closed, }
Состояния изменяются под воздействием событий:
#[derive(Debug)] enum Event { Message { meaningful: bool, }, Meeting { comfortable: bool, }, Boundary { respected: bool, }, Conflict, RepairAttempt, Silence, }
А сама связь содержит не только текущий этап:
#[derive(Debug)] struct Relation { stage: Stage, interest: f32, trust: f32, uncertainty: f32, communication_cost: f32, }
Одна удачная встреча не переводит систему напрямую из Unknown в Partnership.
Скорее она немного меняет внутренние параметры:
impl Relation { fn apply(&mut self, event: Event) { match event { Event::Message { meaningful: true } => { self.interest += 0.1; self.uncertainty -= 0.05; } Event::Meeting { comfortable: true } => { self.trust += 0.15; self.interest += 0.15; self.uncertainty -= 0.1; } Event::Boundary { respected: true } => { self.trust += 0.2; } Event::Boundary { respected: false } => { self.trust -= 0.3; self.communication_cost += 0.2; } Event::Conflict => { self.trust -= 0.1; self.uncertainty += 0.2; } Event::RepairAttempt => { self.trust += 0.1; self.uncertainty -= 0.1; } Event::Silence => { self.uncertainty += 0.1; } _ => {} } self.interest = self.interest.clamp(0.0, 1.0); self.trust = self.trust.clamp(0.0, 1.0); self.uncertainty = self.uncertainty.clamp(0.0, 1.0); self.communication_cost = self.communication_cost.clamp(0.0, 1.0); } }
Конечно, реальные люди устроены сложнее. Один и тот же сигнал разные системы обрабатывают по-разному.
Для одного молчание означает спокойствие. Для другого — потерю интереса. Для третьего — попытку наказания.
Событие одинаковое, интерпретаторы разные.
Почему первое свидание часто выглядит искусственно
В обычной жизни общение появляется вокруг внешней задачи.
Люди работают над проектом, учатся, ремонтируют автомобиль, спорят о фильме или пытаются понять, почему production снова упал в пятницу вечером.
На свидании объектом исследования становятся сами участники.
Возникает рекурсивная конструкция:
Я оцениваю её. Она оценивает меня. Я думаю о том, как она меня оценивает. Она может заметить, что я думаю о том, как она меня оценивает. Теперь я пытаюсь выглядеть так, будто ни о чём этом не думаю.
Количество уровней абстракции быстро превышает возможности системы.
Человек может быть совершенно свободным в знакомой компании, но оказаться скованным на встрече один на один. Это не обязательно означает отсутствие социальных навыков.
Навык свободно разговаривать и навык спокойно переносить явную взаимную оценку — разные интерфейсы.
Первая встреча поэтому часто напоминает интеграционный тест двух систем, документация к которым отсутствует.
Неопределённость удерживает внимание
Стабильный положительный сигнал приятен, но предсказуем.
Неоднозначность заставляет мозг постоянно пересчитывать модель:
Она заинтересована или просто вежлива? Это был флирт или буквальный вопрос? Почему ответ пришёл через две минуты? Почему сообщение удалено? Встреча действительно прошла хорошо или человек просто не хотел обидеть?
Каждый новый сигнал приносит небольшое обновление состояния. Возникает механизм, похожий на переменное подкрепление: награда появляется нерегулярно, поэтому система продолжает проверять её источник.
Из этого следует неочевидная вещь:
Мы можем много думать о человеке не потому, что он нам особенно нравится, а потому, что связанная с ним ситуация остаётся незавершённой.
Незакрытый гештальт — своего рода процесс, который продолжает работать в фоне и периодически съедает CPU.
loop { update_model(); search_for_hidden_meaning(); sleep_for_a_while(); }
Проблема в том, что sleep_for_a_while() иногда длится около трёх минут.
Совместимость — это не количество общих фильмов
Обычно при знакомстве люди ищут совпадения:
одинаковую музыку;
любимые сериалы;
общие профессии;
похожее отношение к отдыху;
один знак зодиака, если совсем закончились методы типизации.
Но общие интересы — это преимущественно стартовый протокол. Они помогают установить соединение, но почти ничего не говорят о качестве дальнейшей эксплуатации.
Совместимость можно условно разделить на три уровня.
Базовый
Безопасность, физическое принятие, отсутствие сильного отторжения.
Функциональный
Темп жизни, отношение к деньгам, сексу, детям, быту, работе, личной свободе и конфликтам.
Символический
Юмор, язык, культурный контекст, интеллектуальная манера и ощущение:
Этот человек понимает мой способ видеть мир.
Два человека могут слушать одну музыку и при этом совершенно по-разному обрабатывать коммуникацию.
Один говорит намёками. Второй воспринимает буквально. Один считает молчание комфортным. Второй видит в нём отказ. Один использует иронию. Второй каждый раз запрашивает документацию.
Технически системы совместимы. Но между ними появляется дорогой слой преобразования:
Person A -> encode -> ambiguous message -> decode -> clarification request -> re-encode -> explanation -> Person B
Чем чаще требуется такой перевод, тем выше communication_cost.
Различия сами по себе не являются проблемой. Проблемой становится цена их постоянного обслуживания.
Ownership: никто никому не принадлежит
Метафора ownership здесь опасна: в отношениях человек не является объектом, которым можно владеть.
Но Rust хорошо иллюстрирует другую идею — ответственность за собственное состояние.
struct EmotionalState { anxiety: f32, expectations: Vec<String>, boundaries: Vec<String>, }
Каждый участник владеет своим состоянием:
let my_state = EmotionalState::new(); let your_state = EmotionalState::new();
Передать другому человеку ответственность за его полное регулирование нельзя:
// Плохая архитектура: you.must_keep_me_happy_forever();
Партнёр может временно участвовать в регулировании состояния — поддержать, успокоить, выслушать. Но это скорее borrowing, а не передача ownership.
fn support(state: &mut EmotionalState) { state.anxiety *= 0.8; }
Ссылка может быть очень важной. Но исходное состояние всё равно остаётся частью системы конкретного человека.
Границы и borrow checker
В Rust нельзя бесконтрольно получить несколько изменяемых ссылок на один ресурс. В человеческих отношениях формального компилятора нет, но конфликты ресурсов никуда не исчезают.
Время, внимание и эмоциональная энергия конечны:
struct Resources { time: u32, attention: u32, emotional_energy: u32, }
Когда работа, отношения, несколько параллельных связей, собственный проект и необходимость иногда спать одновременно запрашивают:
&mut attention
компилятор не остановит программу.
Она просто начнёт вести себя непредсказуемо в runtime.
Границы — это не способ усложнить чужой доступ. Это описание допустимого API:
trait Communication { fn acceptable(&self, message: &Message) -> bool; }
Проблемы начинаются не тогда, когда у человека есть требования, а когда интерфейс скрыт, меняется во время исполнения или сопровождается агрессивными ошибками без документации.
Что обычно называют химией
«Химия» выглядит как единое мистическое чувство, но механически она может состоять из нескольких процессов:
сенсорное влечение;
достаточная безопасность;
небольшая непредсказуемость;
взаимное подтверждение интереса;
удовольствие от реакции другого;
автоматическое возвращение внимания;
моделирование будущих взаимодействий.
Когда эти процессы усиливают друг друга, возникает петля обратной связи:
attention -> pleasant reaction -> increased significance -> more attention -> stronger reaction
Можно описать это и так:
fn interaction_loop(mut significance: f32) -> f32 { for _ in 0..10 { let attention = significance * 0.6; let reward = attention * 0.7; significance += reward * 0.2; } significance }
Разумеется, любовь не вычисляется через f32.
Но сама идея положительной обратной связи полезна: значение человека не всегда существует заранее. Оно может постепенно формироваться благодаря последовательности взаимных реакций.
Как появляется привязанность
Сначала новый человек является источником стимуляции, его сообщение интересно, потому что оно новое. Встреча важна, потому что уменьшает неопределённость. Затем при повторяющихся контактах человек может стать источником предсказуемости и внутренней регуляции.
Грубая последовательность выглядит так:
enum AttachmentStage { Novelty, MutualEvaluation, Reinforcement, Habit, EmotionalRegulation, SharedIdentity, }
Новизна
«Интересно, кто это».
Взаимная оценка
«Насколько я ему или ей нужен?»
Подкрепление
«Контакт приносит удовольствие».
Привычка
«Этот человек встроен в мой день».
Эмоциональная регуляция
«Его присутствие меня успокаивает, а отсутствие начинает ощущаться».
Совместная идентичность
Вместо двух независимых биографий появляется некоторое «мы».
Многие знакомства прекращаются на первых двух стадиях. Иногда люди несколько лет остаются на стадии привычки, ошибочно принимая её за партнёрство.
Алкоголь как unsafe
В Rust unsafe не означает, что код обязательно неправильный.
Это означает, что часть гарантий временно становится ответственностью программиста.
Алкоголь действует похожим образом:
снижает самонаблюдение;
уменьшает страх оценки;
сокращает цепочку между импульсом и действием;
ослабляет проверку возможных последствий.
В трезвом состоянии процесс может выглядеть так:
impulse -> risk analysis -> prediction of reaction -> wording correction -> another prediction -> action
После нескольких напитков:
impulse -> action
Именно поэтому пьяное общение иногда кажется более естественным.
Но алкоголь необязательно раскрывает «настоящего человека». Скорее он временно отключает часть проверок.
unsafe { say_exactly_what_came_to_mind(); }
Иногда программа продолжает работать быстрее и веселее.
Иногда выясняется, что инварианты всё-таки существовали не просто так.
Почему человек знакомится, даже когда ему лень
Мотивация не является одной переменной.
Одновременно могут существовать несколько процессов с разными временными горизонтами:
struct Motivation { immediate_comfort: f32, sexual_interest: f32, curiosity: f32, need_for_validation: f32, desire_for_partnership: f32, desire_to_avoid_change: f32, }
Краткосрочная система хочет остаться дома. Среднесрочная хочет эмоций, секса или подтверждения привлекательности. Долгосрочная хочет близости, партнёрства или семьи. Эти процессы не обязаны приходить к единогласному решению. Поэтому человек может не хотеть идти на конкретное свидание, но при этом хотеть результат, который появляется только после множества подобных встреч.
Это не обязательно самообман. Это конфликт временных горизонтов.
Любовный сценарий не компилируется заранее
В начале почти никто не знает, станет ли конкретное знакомство важным.
Любовная история обычно появляется ретроспективно, после того как случайная последовательность закрепилась:
люди одновременно оказались доступны; возникла минимальная симпатия; контакт повторился; никто не исчез слишком рано; появились общие переживания; возникла привычка; сформировалась взаимная значимость; история была переосмыслена как закономерная.
Снаружи это может выглядеть как судьба.
Изнутри — как множество небольших переходов, на каждом из которых система могла завершить работу.
fn relationship() -> Result<Partnership, ConnectionClosed> { establish_contact()?; survive_ambiguity()?; meet_in_person()?; build_trust()?; handle_conflicts()?; create_shared_context()?; Ok(Partnership::new()) }
Оператор ? здесь особенно важен.
Любой этап может вернуть ошибку, и это не обязательно означает, что один из участников плохой. Иногда системы просто не смогли согласовать протокол.
Вместо заключения
Люди знакомятся не потому, что мгновенно распознали «своего человека». Обычно небольшого интереса оказывается достаточно, чтобы выполнить ещё один шаг и собрать дополнительную информацию. Затем система либо закрывается, либо начинает приобретать собственную инерцию.
В этом смысле любовь — не заранее написанный сценарий и не магическое совпадение двух идеальных объектов.
Это процесс, в котором:
неопределённость постепенно превращается в знание;
повторяющийся контакт — в привычку;
привычка — в значимость;
отдельные состояния — в общее пространство;
два независимых процесса иногда начинают сознательно поддерживать один runtime.
Компилятор здесь не гарантирует безопасность. Документация всегда неполная. Тестовая среда не совпадает с production. А некоторые ошибки обнаруживаются только спустя несколько лет эксплуатации.
Но, вероятно, именно отсутствие полной гарантии и делает запуск настолько интересным.
Спасибо что дочитали.
EgorSharin
Неожиданно…
Напомнило:
“Снятся ли андроидам электрические овцы?” Филипа Дика.
А я вот влюбился в С++. Прям по уши втрескался. И изменил с ней своей старой C#.
vaalimusic Автор
Странно изменять дочке с ее мамашой.