Обновить
25
0
ApeCoder@ApeCoder

Разработчик

Отправить сообщение

В приткладном — свой мир со своими бизнес правилами. Пользователю нельзя давать выстрелить себе в ногу. И не только себе.

и следить за границами

следить за соблюдением каких правил?


Код ревью.

А что-то автоматическое?

Я так понимаю, что в микросервисах огранисения типа агрегатов DDD — нельзя например передавать ссылки, на что-то внутренне а только value object. Пакеты это никак не ограничивают.

Интересно, не придумал ли кто-то способа энфорсить слабо связанную архитектуру, не заставляя маршалить данные и взаимодействовать по сети?

сли такой договор есть и мы верим, что человек, который ф-ю писал, ему следует — то надо, с-но, посмотреть на имя функции/тип/документацию и выяснить, вызывает она внутри print или нет.

Если договоренность есть, то можно написать инструмент, который будет проверять это. Если договоренности нет, то придется исследовать все дерево вызовов.


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


100% гарантии никогда нет — бывают ошибки в компиляторах или рантаймах.


Если же договоренности нет (или веры нет) — только тело смотреть, других вариантов не остается.

Т.е. есть разница между наличием и отсутствием договоренностей?

Причем этот ризонинг делаться будет совершенно одинаково что в хаскеле, что на сишке.

Это касается абсолютно всех программ программ на хаскеле или только того подмножества где есть только монада IO и ни одной функции не использующей этой монады?

А можно — как "композиция ф-й Stack -> Stack", никаких сайд-эффектов, чистая функциональщина.

Можно предложить разделение на формально-функциональную и функциональную по духу программу.


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


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

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


Еще мне интересно как вы автолифтанете reflection. Я не очень во все этих монадах. Но мне кажется, что тогда из семантики языка придется убрать всякие int и прочее и оставить только IO int либо думать о что MethodInfo.GetParameterType возвращает анлифченный тип параметра.

Это только если вы придумаете свой язык с синтаксисом, допустим C#, и будете приписывать ко всем функциям IO (назовем его, допустим IO#). В реальном языке C# никакого IO, его нет в документации библиотеках и reflection. Язык — это договоренность относительно того, что, что означает.


Как только вы придумаете такой язык, он будет бессмысленным, так как там будет две категории функций — те, к которым осмысленно приписано IO типа Console.WriteLine и те, к которым бессмысленно приписано IO типа String.Concat и нет никакого способа не приписывать IO к функциям и от этого приписывания нет никакой выгоды.


Т.е. вы можете мысленно транслировать C# на очень похожий бессмысленный язык IO# но


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


  2. это будет бессмысленный язык так как на нем не будет возможности не приписывать IO к функциям.


Я так понимаю, что когда она интерпретируется то тоже нет сайд эффектов, так как состояние мира передается как RealWorld

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


int Factorial(int n)
{
    Log.Info($"Computing factorial of {n}");
    return Enumerable.Range(1, n).Aggregate((x, y) => x * y);
}

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

Представьте себе, что в условном C IO написано просто везде, поэтому, чтобы не захламлять программу, договорились его нигде не писать явно — компилятор проставит

Если компилятор проставит, то это значит изменение типа — т.е. я смогу например в своей функции мемоизации проверить не содержит ли тип IO и принять решение могу ли я мемоизировать эту функцию или нет.


Рассуждения Druu верны если отбросить то, что у библиотек, компиляторов, IDE, RTTI и других людей уже есть некоторое соглашение о том, что является типом и аргументами функции а что — нет.


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

С моей точки зрения она всегда чистая (я не очень силен
монадах). Просто когда вы ее выполняете внутри монады завернут RealWorld (состояние мира) и оно всегда разное, а способов его генерировать запоминать и не возвращать не бывает.


Функция чистая не тогда когда у нее нет эффектов, а когда нет побочных эффектов — т.е. чего-то не являющимся возвращаемым значением. Если представить состояние всего мира как аргумент и
возвращаемое значение (типа такая особенная гигантская стейт монада) то это чистая функция — она не делает ничего что не является трансформацией аргумента в результат, т.е. нет побочных эффектов.

что является не лучшей идеей

Тут битая ссылка


Как модератор, я хочу создать новую игру, введя название и необязательное описание.
Или же:
Я хочу создать новую игру, введя название и необязательное описание.
Неужели небо рухнуло?

Если я сисадмин, я могу сделать это скриптом — мне нужна автоматизируемость, если я модератор, у меня должен быть удобный интерфейс. Если я игрок, у меня могут быть урезанные права, например.

Допустим вы воспринимаете программу на C как синтаксический сахар для программы на haskell, где все функции подняты в IO.


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


Т.е. все функции поделятся на два типа, которые декларируют использование IO и его на самом деле используют и те, которые декларируют использование IO но его не используют.


Как только вы мысленно уберете IO из типа этих функций у вас будут ошибки мысленной компиляции.


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

Так а какая разница?

Разница в том, что автор считает чисто функциональной программу в которой есть одно гигантское определение чистой функции внутри которого грязный код


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

Я не очень понимаю, что такое "содержательный способ" в данном случае. В моем представлении речь идет о том из кусков какого типа мы составляем программу — то есть о форме записи алгоритма.


Если является — то грязных функций не существует, т.к. любую грязную ф-ю в любом языке можно рассматривать как функцию, возвращающую ИО.

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


Мы можем, конечно, себя ограничить и написать формально чисто функциональную программу написанную в императивном стиле, как допустим, мы можем написать объектно ориентированный эмулятор оборудования на C# и писать все на нем (типа processor.Registers.Ax.Move(processor.Registers.Bx)). Но тогда у нас, по крайней мере, будет способ заводить новые чистые функции и они будут отделены от IO/RealWorld.


Что вы подразумеваете под "чистой ф-ей" в данном случае?

"В языках программирования, чистая функция, это функция, которая:


  • является детерминированной;
  • не обладает побочными эффектами"

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


Это определение относится не к тому, что делает программа, а из чего она собрана — т.е. это некоторый способ соединения частей программы.


Это полезно, например, для того, чтобы понимать какие преобразования мы можем делать с программой без нарушения ее работы.


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

трехвинтовой квадрокоптер.

"Квадро" означает "четыре". Это трикоптер.

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


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

На codereview могут указать на неправильную терминологию. А переименовать ее достаточно легко — ide помогут.

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность