Escapist Marginalia

User Preferences

Interface language

Theme

rational

Rational - библиотека, добавляющая поддержку рациональных чисел в JavaScript.

Обновлялось

Истоки проекта#

Проект уходит корнями к дальнему прошлому, датируемому ещё до моего увлечения веб-разработкой. На тот момент я только изучал основы python (дальше знакомства с основами дело, увы, не зашло). Ознакомившись с различными типами данных и изучая ООП, пришла идея реализовать поддержку рациональных чисел c более обширным интерфейсом, нежели предоставленный в то время и в том виде модуль Fraction. Вполне возможно, что в контексте самого языка с учётом имеющегося уже модуля, я переизобретал велосипед. Вполне возможно так оно и было. Тем не менее, задача была мне под силам и непосредственно интересна.

Проект получился и я был доволен результатом; благодаря нему смог лучше проникнуться принципами ООП, узнать достаточно много нового. Разумеется, проект нигде не был опубликован и был благополучно забыт где-то в архивах файловой системы ноутбука.

Мотивация#

Спустя время, как это можно заметить за многими моими проектами, решил вернуться вновь и попытаться реализовать проект снова. Только в тот момент я уже был веб-разработчикам и основным моим языком был (какая неожиданность!) — JavaScript. В отличие от того времени я уже имел некоторый опыт, уверенно владел языком и лучше понимал процесс работы над проектами и процессы, связанные с ними.

JavaScript сложно сравнивать с python, подходы к ООП разительно отличаются друга от друга (да, в JavaScript нет ООП как такого). В JavaScript отсутствует возможность работы с рациональными числами и наличие такой возможности могло бы действительно принести пользу моим потенциальным проектам, а возможно и даже сообществу. Было решено написать полноценную библиотеку и опубликовать её на npm.

Процесс#

Работа над библиотекой оказалась довольно приятной и продуктивной. Перед тем как написать первую строчку кода, изучил уже существующие решения для лучшего понимания функционала для достаточной конкуренции и в целом, понимания пользовательских требований к аналогичным решениям. Создание проекта оказалось разумным шагом, так как существующие альтернативы были написаны относительно давно, без использования современных возможностей JavaScript и все же не было того проекта, который бы собрал всё лучшее воедино.

К тому моменту уже имелся опыт публикаций пакетов, понимание необходимых для того процессов, настройки окружения и умения писать модульные тесты. Проект был реализован с использованием TypeScript. По итогу, в сжатом виде библиотека умещалась в 2кб, что мне показалось весьма неплохим показателем, учитывая реализованный функционал.

Пользовательский ввод#

Все библиотеки с поддержкой рациональных чисел имеют более или менее схожий интерфейс: предоставляется возможность создавать экземпляры объекта и проводить с ними операции. Почитать более подробно о функциональности rational можно в документации. Здесь же хотелось бы выделить достаточно гибкий пользовательский ввод:

  • (n?: int = 0, d?: int = 1) — целочисленные значения числителя и знаменателя двумя параметрами;
  • (input: [ n: int = 0, d?: int = 1 ]) — целочисленные значения числителя и знаменателя массивом;
  • (input: { int?: number = 0, n: int, d?: int = 1 }) — целочисленные значения целой части, числителя и знаменателя объектом;
  • (input: StringFraction) — строки в формате дробного выражения в формате "{sign?}{numerator}/{sign?};
  • (input: RepeatingDecimal) — периодической дроби в виде объекта;
  • (input: StringRepeatingDecimal) — строки в виде периодической дроби в формате {sign?}{int?}.{non-repeating}?({repeating});
  • (input: Degrees) — градусной меры в виде объекта;
  • (input: StringDegrees) — градусной меры в виде строки в формате {sign?}{degrees?}.{minutes'?}{seconds''?}.

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

Резюмируя#

Библиотека сама по себе не является чем-то выдающимся, написать такое вполне может любой разработчик с парой лет опыта. Тем не менее, я оказался доволен результатом, что случается крайне редко из-за завышенных требований к самому себе. Библиотека типизированна, предоставляет необходимые типы, покрыта тестами, имеет достаточно неплохую документацию и покрывающий все потребности функционал. В случае необходимости rational поддерживает расширяемость и в целом, использовался современный JavaScript.

У библиотеки присутствуют некоторые очевидные ограничения связанные с числовым типом Number, а именно с максимальным целочисленным значением. Была идея использовать BigInt, но меня посещали сомнения касательно необходимости в таких больших значениях при использовании библиотеки. Особенно учитывая падение производительности (до 10 раз).

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