Pull to refresh

Comments 5

Мне всегда интересно читать о собственных реализациях чего бы то ни было. Именно из такого рождаются новые ниши и стандарты. Спасибо что поделились, я знаю как не просто на это решиться в наше время : )

Но есть вопрос. Разве создание копии массива в момент переопределения его элемента - не ведет к путанице при отладке? По моему в таких случаях проще вызывать явное копирование массива. И как быть, если понадобилось изменить исходный массив, имея ссылку на него? По моей беглой оценке, поведение, описанное в статье требуется в очень редких случаях. Буду рад если мои рассуждения ошибочны : )

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

Сравните:

var data = ReadData();
EnrichData(data);
return data;
let rawData = ReadData();
let mappedData = EnrichData(rawData);
return mappedData;

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

более функциональному стилю, который среди прочего требует иммутабельности

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

И как быть, если понадобилось изменить исходный массив, имея ссылку на него?

В языке нет ссылок.

По моей беглой оценке, поведение, описанное в статье требуется в очень редких случаях.

Я увлекаюсь программированием вот уже 21 год и за всё это время, самые сложные в исправлении баги с которыми я сталкивался, были вызваны тем, что есть несколько ссылок на объект и происходит запись по ссылке, которая была рассчитана только на чтения. Такая проблема обычно сразу себя не проявляет, а программа некоторое время работает, а затем происходит ошибка, при этом код который вызвал ошибку полностью корректен и никак собственно с проблемой не связан. Бывало что я тратил десяток часов на поиск и исправление ошибок. Подход используемый в Shar делает невозможным совершение подобных ошибок.

Также некоторое время я программировал на Haskell и мне очень нравилось то, что не нужно париться про состояние данных вне функции, что позволяет абстрагироваться от всего кода и сфокусироваться на одной функции. Тоже самое и в Shar, только в Haskell это достигается за счёт иммутабельности, а в Shar за счёт невозможности изменить данные одного объекта при изменении другого.

Разве создание копии массива в момент переопределения его элемента - не ведет к путанице при отладке?

Сейчас никакого отладчика нет. Честно признаюсь - последний раз я пользовался отладчиком лет 10 назад, но из моих воспоминаний я не понимаю почему должна быть путаница.

По моему в таких случаях проще вызывать явное копирование массива.

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

Sign up to leave a comment.

Articles