"Да какой ты на[фиг] оптимизатор? хать, тфу."
Проблема
Пришёл в новый проект где было подключено три математические библиотеки. Кодовая база впитала опыт нескольких команд разработчиков и представляла типичный legacy где обосновать то или иное решение не всегда представляется возможным. Дойдя в бэклоге до оптимизации я стал перебирать варианты того, как это можно решить. В результате своих размышлений я пришёл к выводу, что хочу сохранить все имеющиеся библиотеки, но убрать с глаз разницу в API. Желаю конфигурировать на лету "математический движок" в одной точке (не залезая в, непосредственно, сам клиентский код).
Решение
Синтаксис математических выражений основанный на массивах (назвал nemathode и создал под него отдельную страничку со всей информацией которая поможет втянуться в этот механизм). Я хотел, чтобы он был максимально близок к большинству популярных языков, но в первую очередь к JavaScript.
То есть, сильно ничего не меняется:
круглые скобки меняются на квадратные;
операторы (константы, имена функций) обрамляются в кавычки;
а конфигурация происходит в одной точке (до которой мы скоро дойдём).
![Схематично о смысле синтаксиса Схематично о смысле синтаксиса](https://habrastorage.org/getpro/habr/upload_files/748/1f6/58b/7481f658b4b24de24298ea3e779f0e4f.jpg)
Применив эту штуку я теперь могу:
продолжать использовать кучу математических библиотек и конфигурировать их в одной точке скрывая детали API
добавлять новые методы, операторы, константы и выбирать удобное именование;
калибровать точность и скорость вычислений на лету (корректировать текущие имплементации, заменять математические константы с более подходящими значениями).
Примеры использования
Бинарные операторы
Функции
Математические константы
Вложенные выражения
Пример конфигурации
Больше примеров настройки библиотеки можно найти здесь
mathConstants
Буквально, математические константы
functions
Набор имплементаций
toInputType
Это кажется избыточным, но не все используют функциональность чистого JS. Существует ряд библиотек где промежуточным типом в вычислениях не является число (bignumber.js, decimal.js). Таким образом мы можем настроить этот обработчик как на примере ниже
toOutputType
Противоположен toInputType. Смотрите пример ниже
binaryOperators
API - стандартное
API - с любовью ❤️
Послесловие
Вдохновлялся
Вопросом на stackoverflow
Несколькими задачами на codewars (не помню названия)
math.js библиотекой и её механизмом вычислений
В будущем (если решение пригодится не только мне)
Полное TS покрытие (чтобы был автокомплит по операторам при написании выражений)
Унарные операторы (до сих пор сомневаюсь по поводу их необходимости. Нужна Ваше мнение)
Обработка аргументов функции
Преодолеть ограничения связанные с возвращаемыми типами значений (number, boolean etc)
И напоследок
Если у Вас есть вопросы, предложения, пожелания, критика - я буду рад услышать обратную связь в любой форме. Ссылка на вебсайт со всей необходимой информацией.