Задача оказалась проще, чем я предполагал, однако потратил на эти несколько функций не один день.
Итак, шаблон таблицы упорядоченного по хэшам списка, можно считать готовым. Значит можно создавать таблицу функций.
Задача оказалась проще, чем я предполагал, однако потратил на эти несколько функций не один день.
Итак, шаблон таблицы упорядоченного по хэшам списка, можно считать готовым. Значит можно создавать таблицу функций.
Задался вопросом, как хранить данные в таблицах приложения.
Вопрос не простой, потому что хотелось бы получить быструю работу с памятью - как в связанных списках, но и быстрый доступ - сравнимый с доступом к элементам массива.
Придумал следующее решение. Хранить данные в списках например по 16 элементов на список. А указатели на списки хранить в массиве, память в котором тоже выделять блоками.
Тогда при поиске элемента можно будет посмотреть первый и последний элементы в списке - попадает ли искомый хэш в данный диапазон или нет. И если попадает, то дальше искать элемент уже в этом списке, а если нет - то, искать в меньшую или большую сторону.
Суть оптимизации проста - мы как бы имеем связанный список, отсортированный по возрастанию хэша, но имеем возможность перебирать его элементы методом прыжков, который весьма эффективен.
Но могу ли использовать контейнеры C++? - спросил я самого себя, и решил, что там вряд ли используются самые эффективные алгоритмы. Ещё до этого меня неприятно поразило, насколько в общем виде там всё реализовано, когда я увидел их исходник в отладчике.
Так что сегодня я засел писать эту свою таблицу элементов, благо этот код должен получиться достаточно универсальным - я сразу стал писать шаблон.
Понял, что мне мешает сосредоточиться, когда я программирую. Как ни странно, это неведомо откуда появляющееся ощущение еле заметной паники. Как будто я пытаюсь что-то испортить, а не создать нечто новое.
Память подсказывает, что первый раз я с этим столкнулся, когда писал сценарии. Тогда это чувство бывало настолько сильным, что мне приходилось буквально продираться через эту пелену, сочиняя что-то совсем уж наобум - настолько не соображал от ужаса мозг.
Но я заметил, что правильная музыка помогает это чувство приглушить. Или наоборот - усилить.
Долго я исследовал причины, пока наконец не понял, в чём вопрос.
Чтобы начать новый проект, требуется погрузиться в зону комфорта. Расслабиться, успокоиться, ни о чём не беспокоиться.
Но затем, начав писать, требуется работать, ни на что не отвлекаясь, по возможности быстро. И вот это "быстро" пугает, потому что становится страшно сделать ошибку. Чувство комфорта и защищённости рассеивается, и вместе с усталостью возникает паника.
Чего я только не перепробовал, чтобы сохранять чувство комфорта во время работы. Пока не открыл метод самозапугивания.
Ведь если я настолько боюсь чего-то не слишком реального, каких-то иллюзий, то нужно просто напугать себя ещё сильнее.
Например: а что, если за мной шпионят? - такой страх например посещает.
Начинаю себя запугивать: а что если за мной шпионят наркоманы, которым не хватает на дозу? - это ведь намного страшнее.
А что, если именно я когда-то посоветовал им попробовать наркотики, но давно об этом забыл? - ещё страшнее вариант.
И так далее. В какой-то момент мозг начинает протестовать против подобной ахинеи, и страх уходит.
Но сейчас я вспомнил причину. Причина в том, что по мере роста объёма текста или кода начинаешь забывать, что было до этого. И панику вызывает именно эта потеря определённости.
Ведь наши воспоминания как бы формируют для нас основу уверенности в себе. Если вам только что стёрли память, то это не страшно, потому что вы не помните своих иллюзий, питавших ваши страхи.
Но по мере накопления неприятного опыта, появляется чувство тревоги, с которым легко бороться например с помощью алкоголя. Но когда работаешь, нужно быть трезвым, и по мере усталости этот страх нарастает, пока не становится совсем уж ужасно.
При этом как мы боремся со страхами? Да просто спрашиваем себя: а чего я боюсь в данный момент?
А тут вы можете ответить себе только: я не помню, я слишком устал.
Сегодня конечно был сложный день. Я не выспался и написал не очень много кода. Спать вроде не хочу, а работать уже не могу - надо как-то отдыхать. Видимо придётся выпить бокальчик рома с кока-колой.
Не особо хочется, потому что алкоголь меня бодрит.
Не так-то просто начать не с функции calc_hash - ведь она используется для поиска по таблицам объектов и функций.
Немножко повозился с консолью терминала. Новый алгоритм работы в терминале потребовал изменить логику потоков. Которая получается отличной от концепции терминала в языке C.
В C мы имеем три потока:
Новый алгоритм предлагает четыре потока:
Хотел поработать много, но поработал мало, а день таки прошёл.
Неожиданно для себя я увидел следующий алгоритм работы в терминале.
Пользователь вводит текст, и этот текст записывается в файл. Но если он ввёдет на конце строки некий код (например ===), то терминал переключится в режим ввода управляющих команд. А затем, введя ===, можно будет продолжить ввод текста или данных.
Гениально, - сказал я самому себе. - Это почти как вставки кода в веб-страницах.
Поэтому вместо ставших уже традицией функций exec и calc_hash, я решил написать функции чтения текста из файла и записи текста в файл.
Почитал, что я тут написал в блоге. Честно говоря, про это устаёшь даже читать - не то, что этим заниматься.
Не помню, почему возник перерыв в работе. На меня снизошло благословение Небес, и я вдруг начал писать музыку. Писал, писал - пока не написал альбом.
Затем начались бомбардировки, и я больше не мог ничем заниматься - всякое занятие вызывало у меня приступ паники. Как будто сейчас меня начнут бомбить за это.
Но вот, боевые действия затихли, и теперь можно снова заняться чем-нибудь полезным.
Не то, чтобы я совсем терял время впустую весь этот период. Я начал изучать JavaScript и освежил в памяти сведения по нейросетям.
К проекту своего языка мне с одной стороны вроде бы хочется вернуться, поскольку по своему опыту я знаю, что так или иначе всё упрётся в необходимость этой программы. Но с другой стороны мне хочется попрограммировать нечто более развлекательное - какую-нибудь 3D-графику или нейросети.
Парадокс нейросетей я бы сформулировал так. Ими можно управлять, только если добавить классификатор.
Например, логический элемент A & B -> C. Результат его работы - классификация входящих данных: A и B.
Мы можем добавить класс D - получится A & B -> C, D. Пока что всё ОК.
Но что, если A и B - это два пикселя картинки, C и D - тоже два пикселя, а нейросеть - это такой фильтр: почему A не B, как это изменит C и D?
И вот тут получается, что нейросеть, инициализированная случайными значениями, даёт случайный результат. Чтобы определить закономерность для пикселей C и D, нам требуется ввести классификацию, с помощью которой управлять работой нейросети.
Но ведь мозг человека каким-то образом имеет классификатор, который сообщает нам, что яблоко не должно быть фиолетового цвета. Или почему бы и нет, и всё дело только в среде, в которую нас помещает предназначение?
Всё это связано с моей программой таким образом, что я так и не смог ответить самому себе на вопрос, что именно я собираюсь автоматизировать.
Вот, например, язык JavaScript. Есть браузер, задача которого - показать веб-страницу. И вот язык скриптов, который позволяет пользователю автоматизировать взаимодействие пользователя с этой веб-страницей.
Этот язык создан именно для этого, и больше нигде (разве что кроме плат Iskra Neo) не применяется.
А я свой язык стал создавать, не имея перед собой цели - что именно я хочу автоматизировать. Поэтому задача выглядит слишком абстрактной, и поэтому объём работы получается невероятно гигантским. Просто удивительно, насколько много самого разнообразного кода написали люди на том или ином языке.
Формально я как бы просто пытался сделать лексический транслятор, который позволил бы автоматизировать разработку программ.
Вот, допустим, мы хотим создать DSP на языке Verilog. Но средства этого языка не позволяют использовать классы и объекты. Это условный, хотя и наглядный пример.
Поэтому именно Форт меня этим привлёк. Тем, что предлагает инкапсулировать логику в простых функциях, не усложняя программу по мере роста её кодовой базы.
Но я приводил здесь пример работы со строками:
Дело в том, что элементы Форта были в ней привлекательной частью. Но работа со строками получилась очень странной из-за этого. Только представьте - как выглядит функция substr на объектном Форте:
"Hello World!" 0 5 rot sub_str "Hello" == if
"How are you?" cout <<
;
Здесь мы берём слово "Hello", и если это "Hello", то отвечаем "How are you?". В целом неплохо, но были варианты просто дикие - например разбор аргументов командной строки.
create function add 2
param int x
param int y
result int
return math.add x y
end
Примерно так выглядит псевдоассемблер компилятора. Очевидные достоинства - абсолютно понятная логика. Недостатки - очень сложную функцию очень сложно написать, и следовательно - легко сделать ошибку.
Парадокс, который мне открылся, можно описать так: всё в программе - это набор таблиц. Данные - таблица, код - таблица, и чем лучше они упорядочены, тем лучше работает программа. Поэтому в моей программе нет смысла - ведь если я не могу упорядочить программу на C++, то и любой другой язык мне в этом не сможет помочь.
Тем не менее, сейчас затея снова кажется мне интересной.
Глядя на свой предыдущий код, я вижу, насколько он плохо структурирован. Даже зная, как это работает, невозможно отыскать ошибку.
Простой пример: пользователь вводит "hello и Enter. Консоль сообщает ошибку: глобальное имя "hell не найдено.
Почему символ o пропал? Надо исправить, - сказал я самому себе, и так и не смог отыскать, где же в программе происходит обработка этого токена.
Но читая блог, я понял, в чём моя ошибка - я слишком спешил писать код.
И в самом деле - прошло 2 года, программа так и не написана - так стоило ли спешить?