Re[5]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.02.06 21:28
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Нет, все проще. Есть структурная (топологическая) декомпозиция (основа ООП), и есть функциональная (активно используемая при имплементации ООП). И они прекрасно уживаются и дополняют друг друга.


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

По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения. Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Философический вопрос про автоматический вывод типов.
От: vdimas Россия  
Дата: 13.02.06 23:15
Оценка: 9 (2)
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, vdimas, Вы писали:


V>>Идеальная программная система (похожая на электронные схемы ) — это набор объектов со св-вами и событиями БЕЗ публичных методов и набор функциональных объектов. Да, именно. У объектов — только св-ва и события. Объекты объединяются топологически путем подключения к событиями друг/друга. (Сами собятия могут обрабатываться/трансформироваться функциональным образом, причем как с помощью внешних, то бишь потенциально заменяемых функциональных объектов, так и с помощью внутренних, являющихся частью имплементации объекта... но это я уже повторяюсь).

WH>А вот с этого места по подробней пожалуйста. Как это может выглядеть? Жилательно с псевдокодом.

Сейчас нафантазирую:

Итак. Давай действительно попытаемся представить, почему электронщики умудряются делать довольно сложные устройства "не написав ни строчки кода", т.е. не изготавливая самих мискросхем и прочих деталей, а только лишь топологически соединяя их и выставляя им режимы работы (присваивая значения св-вам). Очевидно от того, что компоненты аппаратуры представлены как наборы пинов — входных и выходных, таких, что эти пины можно по всячески соединять (избегая разве что КЗ )

какие бывают выходные пины:
1. "непрерывного" характера, т.е. такие, на которых в любой момент времени можно получить текущее значение (ближе к аналоговой электронике)

Работать с такими пинами можно по способу pull, т.е. "тянуть" из них значение.

2. сигнального типа, т.е. такие, на которых появляются достоверные сигналы лишь в определенные моменты времени (по такту таймера или в результате прохождения и обработки других внешних сигналов/тактов — ближе к цифровой электронике)

такие пины могут работать как push, т.е. являться источником или распространителем сигнала (события).

Выходной пин первого типа можно описать так:
    public interface IValuePin<T> {
        T Value { get;}
    }


Соответственно, парный ему входной "пин" — это просто св-во объекта соотв. типа:
    public class SomeClass {
        private IValuePin<int> _input1;
            
        public IValuePin<int> Input1 {
            get { return null;  }
            set { 
                if(_input1!=value) {
                    _input1 = value;
                    OnPin1Changed();
                }
            }
        }

        protected void OnPin1Changed() { /* ... */ }
    };


(OnPin1Changed — весьма такой опциональный момент...)


Почему бы "просто не соединить" get_XXX св-во одного компонента с set_YYY св-вом другого компонента? Потому как не существует способа "простого" соединения обычных св-в м/у собой. Весь этот DataBinding в дотнете пляшет как раз вокруг обсуждаемых здесь вещей. но пляшет тупо, коряво, неочевидно и вообще он зашел не с той стороны, напрямую унаследовав биндинг из VB. Для передачи значений м/у св-вами в DataBinding сейчас используются "дополнительные" нотифицирующие события, которые должны отвечать определенным name conventions... для нашего случая в Databinding надо было бы добавить событие "XXXChanging" — для нотификации о необходимости валидации и "XXXChanged" для собственно запуска механизма передачи данных.

Фиг с ним, продолжаем!

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


Пин второго типа можно описать примерно так:
    public interface ISignalPin<T> {
        event Action<T> Signal;
    }


Соответственно, входной пин для второго варианта — это публичное св-во типа Action<T>:
    public class AnotherClass {
        protected void OnPin1(double value) { }

        public Action<double> Pin1 {
            get { return OnPin1; }
        }
    }


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

Именно тут кстати, может возникнуть вопрос — а нахрена выставлять св-ва делегаты в виде пинов, если открытые публичные методы можно использовать с тем же успехом, т.е. использовать их как входные "пины" сигналов. Разница здесь в том, что в этом случае мы можем легко организовать "КЗ", т.е. вне ведома компонента подать на его входной пин, то бишь публичный метод, несколько несогласованных сигналов от разных источников. Пусть согласованием сигналов занимается сам компонент внутри себя и выставляет столько входных пинов, на сколько реально был спроектирован. Например, в реализации класса AnotherClass каждый раз создается новый входной пин при вызове get_Pin1, т.е. допускается произвольное кол-во подключений. Однако, можно было создать закешировать лишь один экземпляр делегата внутри класса и возвращать именно его.

В самом начале обсуждения подумалось — но ведь должны же быть публичные методы хотя бы для манипулирования структурой, например для воссоздания иерархии окошек в GUI, где банально требуются коллекции и методы по управлению содержимым коллекций... продолжая прикалываться можно предложить такое:
    public interface ICollection<T> {
        Action<T> Add { get; }
        Action<T> Remove { get; }
        ISignalPin<int> Count { get; }
        Action<Action<T>> ForEach { get; }
    };


Ты даже можешь подключиться к выходному пину Count, и будешь знать, когда кол-во элементов изменилось.

В принципе, никто не мешает сделать комбинированный пин:
    public interface ISignalValuePin<T> : ISignalPin<T>, IValuePin<T> {}


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

Вот еще разминка к такой коллекции:
    public delegate bool Predicate<T>(T value);

    public class Filter<T> : ISignalPin<T> {
        Predicate<T> _predicate;

        public Filter(Action<T> action, Predicate<T> p) {
            _predicate = p;
            Signal += action;
        }

        public Predicate<T> Predicate {
            get { return _predicate; }
            set { _predicate = value; }
        }

        void OnInput(T value) {
            if (_predicate(value))
                Signal(value);
        }

        public Action<T> Input {
            get { return OnInput; }
        }

        public event Action<T> Signal;
    }

    /** filter demonstration */
    public class Device {
        ICollection<int> _collection;

        private void ActionNotNegative(Action<int> action) {
            _collection.ForEach(
                new Filter<int>(action, delegate(int i) { return i > 0; }).Input
                );
        }
    };


Для ForEach можно лепить произвольные наборы фильтров и предикатов. Схема немного упрощена, вообще-то надо было бы использовать IValuePin<Predicate<T>> Predicate { get; } и IValuePin<Action<T>> Input { get; }

Тогда тело приватного метода Device::ActionNotNegative могло бы сформировано чисто "топологическим" образом без кодирования.

-------
пока хватит — это для затравки. Много еще чего можно придумать, еще обыграть нотификаторы, другие предикаты, многовходовые фильтры и процессоры сигналов (Convert<T1, T2>) и пр и пр. Интересно, а получиться ли составлять (не писать) программы, если нашлепать приличное кол-во подобных кирпичиков на основе неких подобных соглашений?

Из кирпичиков нижнего уровня можно выкладывать кирпичики высокого уровня и т.д.

--------
Визуальный дизайнер мог бы отличать обычные св-ва от входных и выходных пинов по сигнатурам и реализуемым интерфейсам:
IValuePin<T> { get; set; }  // входной пин
IValuePin<T> { get; }       // выходной пин

Action<T> { get; }          // входной пин
ISignalPin<T> { get; }      // выходной пин
ISignalValuePin<T> { get; } // комбинированный выходной пин
Re[6]: Философический вопрос про автоматический вывод типов.
От: vdimas Россия  
Дата: 14.02.06 00:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, vdimas, Вы писали:


V>>Нет, все проще. Есть структурная (топологическая) декомпозиция (основа ООП), и есть функциональная (активно используемая при имплементации ООП). И они прекрасно уживаются и дополняют друг друга.


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

VD>Так, что есть задачи которые принципильно не могут решаться в функциональном виде эффективно.

А зачем реализовывать Set в функциональном стиле???? Ты все-таки не понял мою мысль. Те "объекты" программируемых абстракций, которые априори имеют состояния (и ячейки памяти, их хранящие), не могут быть выражены в чисто-функциональном стиле. Я рассматриваю функциональный стиль как фильтрацию, процессинг сигналов и т.д. Этот стиль замечательно пригоден для функциональной декомпозиции и является отличным дополнением при реализации абстракций реального мира, которые все-таки, легче представлять в виде объектов с памятью (состоянием), как наилучшим образом соотвествующих этим объектам.


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


Да не надо ни на что ориентироваться. Вот у тебя стоит задача модифицировать специальным сложным образом 21-ю ячейку памяти объекта в сложной зависимости от значений других 20-ти. Для написания процедуры модификации лучше всего подходит именно функциональный стиль. Результат последней вычисления последней ф-ии закидываешь в требуемую ячейку. Где нестыковка? Только в том, что некоторые считают, что это отходит от догм?

Функциональный стиль, ИМХО, должен на всю катушку использоваться для имплементации моделей ООП (ОО — модель, ФС — вычисления, производимые в процессе жизни модели, что не так? Модель должна согласованно переходить из состояние в состояние, а сами ф-ии переходов... да именно, могут и должны быть выражены в виде ф-ий).

VD>Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.


Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение. Т.е. тут даже речь не просто о модификации памяти, а об ограничении этой модификации локальным контекстом. Но как раз именно этот момент скорее из разряда обеспечения безопасности/верифицируемости/оптимизируемости, чем из разряда функционального программирования. Например, ты запросто можешь писать на Лиспе в чисто-функционалдьном стиле, не используя императивных расширений, и при этом писать код, который модифицирует общедоступные объекты в памяти (как собственно на нем и пишут).

Далее. на том же Haskell есть бинды к GUI. Что это означает? Это означает, что где-то в памяти все-таки находятся общие объекты. А ф-ии Haskell передают/копируют друг-другу не сами объекты, а их прокси/хендлы. Вот тебе, блин, большая разница и способы уклонения от догм на блюдечке прямо от "производителей" этих догм.
Re[17]: Философический вопрос про автоматический вывод типов
От: IT Россия linq2db.com
Дата: 14.02.06 00:36
Оценка: :))
Здравствуйте, vdimas, Вы писали:

V>Знаешь, пока ЮАЙщикам на дотнет рановато, ей-богу.


Интересно, и чем я на прошлом проекте в Banc Of America Securities занимался?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Философический вопрос про автоматический вывод типов.
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 14.02.06 08:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD> Берем простой пример реализацию Set-а. Реализация его функциональном стиле неминуемо будет не эффективной.


Что значит "не эффективной"?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[7]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.02.06 10:53
Оценка: -2 :)
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Что значит "не эффективной"?


Загляни в словарь.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.02.06 21:49
Оценка: +2
Здравствуйте, vdimas, Вы писали:

V>А зачем реализовывать Set в функциональном стиле????


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

V> Ты все-таки не понял мою мысль. Те "объекты" программируемых абстракций, которые априори имеют состояния (и ячейки памяти, их хранящие), не могут быть выражены в чисто-функциональном стиле.


Я значит не понял? Ты точлько что повторил мою мысль и объяснил мне, что я не понял какую-то твою мысль. Прямо как в том анегтоте про грузинов "спортэ мужчины!...".

V> Я рассматриваю функциональный стиль как фильтрацию, процессинг сигналов и т.д. Этот стиль замечательно пригоден для функциональной декомпозиции и является отличным дополнением при реализации абстракций реального мира, которые все-таки, легче представлять в виде объектов с памятью (состоянием), как наилучшим образом соотвествующих этим объектам.


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

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


V>Да не надо ни на что ориентироваться. Вот у тебя стоит задача модифицировать специальным сложным образом 21-ю ячейку памяти объекта в сложной зависимости от значений других 20-ти.


Так у меня задачи никогда не ставлись. Задачи ставятся по другому. Есть объект и есть его состояние. Изменение состояния эффективно отражается присвоением значений. А это отрицается догмами ФЯ.

V> Для написания процедуры модификации лучше всего подходит именно функциональный стиль.


Модификация автоматически приводит к тому, что мы нарушаем каноны функционального подхода. Что ты там понимаш себе под стилями я даже обсуждать не хочу. Я говорию о другом. Я говорю, о том, что чисто-функциональный подход — это догма приводящая к странным компромисам.

V> Результат последней вычисления последней ф-ии закидываешь в требуемую ячейку.


Это и есть императивный подход.

V> Где нестыковка? Только в том, что некоторые считают, что это отходит от догм?


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

V>Функциональный стиль, ИМХО, должен на всю катушку использоваться для имплементации моделей ООП (ОО — модель, ФС — вычисления, производимые в процессе жизни модели, что не так?


Я не знаю кто такие имплементации. А повторять банальности уже устал.

V> Модель должна согласованно переходить из состояние в состояние, а сами ф-ии переходов... да именно, могут и должны быть выражены в виде ф-ий).


Функции я без проблем могу иметь в императивном коде. Функциональный подход же отрицает модификацию на всех стадиях. Или это уже не ФП. Это еже гибрид. Причем, заметь, я не только за такой гибрид. И по сути я с тобой согласен. Вот только это не ФП. ФП же подразумевает, что модификаций нет вообще. Правда любая реальная реализация даже самых чистых ФЯ обязательно оставляет лазейку для нарушения своих принцпов (вроде монад в Хаскеле). Но это дело десятое. Главное, что при пропаганде ФП без зазрения совести идут расуждения, о том, что модификация некой структуры вроде Set-а приводит к порождению нового Set-а. И мол, умный компилятор сом разберется не произвести ли незаметной модификации (так сказать, за кулисами). Но это в общем-то надежда на случай. Да и не ясно зачем все это.

VD>>Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.


V>Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение.


А, ну, да. Это видимо догмы у меня о ФЯ. А не в ФЯ. Ясно. Всегда проще найти недостаток в оппоненте, чем в его словах.

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


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

Это я извенясю подмена причины следствием.

Объект есть объект. Он существует во времени и изменяет свое состояние. Объект == экземпляр. И не нужно выдумывать концепций нарушающих это.

Конечно есть неизменяемые объекты над которыми можно производить вычисления получая новые копии этих объектов. Такие объекты не редкость в мире ООП. Те же строки или шрифты в дотнете является тому прекрасным подтверждением. Но кроме таких объектов есть еще формы, словари и тысячи других классов объектов для которых идея неизменяемости неприминима.

И лично я толко за если для работы с незименяемыми объектами будет тот самый ФС (стиль, т.е.). Но я против искуственный извращений при работе с теми самыми изменяемыми объектами.

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

V> Например, ты запросто можешь писать на Лиспе в чисто-функционалдьном стиле, не используя императивных расширений, и при этом писать код, который модифицирует общедоступные объекты в памяти (как собственно на нем и пишут).


Нет не могу. Любое изменение состояние есть уход от тех самых догм ФП. А то, что так делают — это лишь доказательство ошибочности этих догм.

V>Далее. на том же Haskell есть бинды к GUI. Что это означает?


Что в Хаскель встроены лазейки позволющие забить на догмы и таки умудриться вывернутся. Просто Хаскеле пытается демонстрировать особую чистоту рядов и вместо того, чтобы допустить императивные конструкции вводит слабо-понятную (точноее вообще не понятную) идею монад. Как следствие возникает необходимость объяснять, что такое монады на уровне буддийских обрадов и пистики.

V> Это означает, что где-то в памяти все-таки находятся общие объекты. А ф-ии Haskell передают/копируют друг-другу не сами объекты, а их прокси/хендлы. Вот тебе, блин, большая разница и способы уклонения от догм на блюдечке прямо от "производителей" этих догм.


Это способы поддержания догм. Мне кажется, что ФЯ слишком идеологизированны, или даже скорее религизированы. Они превращаются в форменную веру. Программист как монах должен во что-то уверовать и чем-то пожертвовать чтобы приобщиться к миру верующих и достичь просветления.

А не проще ли смотреть на все прогматично? ФЯ есть огромное затяжное исследование. В нем было сделано немало наработок. Многие из них были очень успешными. Так почему бы не совместить эти нароботки с наработками в других областях и не получить те самые гибриды. Далее остается только перестать фыркать и создать четкое видение использования такого гибрида. Разобраться для решения каких задач лучше подходит тот или иной подход и применять наиболее подходящие для решения конкретных подзадачь подходы.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Философический вопрос про автоматический вывод типов.
От: Programmierer AG  
Дата: 16.02.06 11:16
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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

VD>Так, что есть задачи которые принципильно не могут решаться в функциональном виде эффективно.
Брось, в стандартной библиотеке всех ФЯ, которые я видел, есть чисто функциональная реализация множеств на чем-то вроде AVL- или Red-Black деревьев, в чем проблема?

VD>По сути функциональное программирование названо не врено. Его следовало бы назвать "Программирование Ориентированные на вычисление выражений". Пока мы занимаемся вычислениями мы можем эффективно записывать код в виде выражений. Но как только мы начинаем вести речь о состоянии, то сразу приходим к модификации памяти и следовательно к отказу от ориентации на выражения. Держась за догмы мы вынуждены копировать объекты, и как следствие неменуемо теряем в производительности.

Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий. Концептуально программа вычисляет новое множество, полученное из старого добавлением элемента, а физически происходит модификация памяти.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Философический вопрос про автоматический вывод типов.
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 16.02.06 11:59
Оценка: +1
VladD2,

VD>Это способы поддержания догм. Мне кажется, что ФЯ слишком идеологизированны, или даже скорее религизированы. Они превращаются в форменную веру. Программист как монах должен во что-то уверовать и чем-то пожертвовать чтобы приобщиться к миру верующих и достичь просветления.


Рубишь с плеча, ажно щепки летят во все стороны Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: Философический вопрос про автоматический вывод типов.
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 16.02.06 12:10
Оценка: +1
VladD2,

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


Называй как хочешь, но прозрачность ссылок — это свойство языка, то есть (абстрактной) нотации, в большой степени характена именно для ФЯ. Реализация может быть (и будет, ибо архитектура x86) императивной. Во многих случаях будет тот же mutable state, только за шторками. Поясню:
A1 = modify(A0).


Если A0 ниже нигде не используется, то многие современные ФЯ (если не все) просто делают модификацию A0.
Если используется и A0, и A1, то можно предложить целую кучу путей:

1. Хранить и A0, и A1, для ссылки A0 использовать A0, для A1 -> A1
2. Хранить A0, и diff(A0,A1), для ссылки A0 использовать A0, для A1 - вычисление A0 + diff
3. То же самое, что и 2, только хранить A1.
4. Хранить некий промежуточный A_, diff(A0, A_), diff(A1, A_);
    A0 -> A_ + diff(A0, A_), A1 -> A_ + diff(A1, A_)


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

Наконец, функции с математической точки зрения — это преобразования. Элементы множества A отображаются на множество B. Всё.

Функции не обязаны заниматься созданием, копированием и какими-бы ни было манипуляции с областями памяти (которые называют объектами, что тоже является сильным сужением философского понятия "объект"). То, как реализуются функции в ЯП — это издержки реализации, не больше.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[7]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.06 14:44
Оценка: 1 (1)
Здравствуйте, Programmierer AG, Вы писали:

PA>Брось, в стандартной библиотеке всех ФЯ, которые я видел, есть чисто функциональная реализация множеств на чем-то вроде AVL- или Red-Black деревьев, в чем проблема?


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

К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы.

PA>Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий.


Ключевые слова здесь "когда это возможно". К тому же таким продвинутым поведением обладают далеко не все компиляторы/рантаймы. Между тем совершенно не ясно в чем проблема использовать то же Set в императивном виде.

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


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

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

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

Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Философический вопрос про автоматический вывод типов.
От: Programmierer AG  
Дата: 16.02.06 15:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.

Устроим шустрик?

VD>К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы.

Эо уже вопрос десятый, ты говорил, что функциональные множества от рождения неэффективны. На C++, C# и Яве направо и налево применяются множества на деревьях.

PA>>Уже неоднократно говорилось, что реализация ФЯ может в случаях, когда это возможно, не делать лишних копий.

VD>Ключевые слова здесь "когда это возможно".
Вызовы функций инлайнятся, когда это возможно. Засовывают переменную в регистр, когда это возможно. Заменяют хвостовую рекурсию циклом, когда это возможно. Аналогия просматривается?

VD> К тому же таким продвинутым поведением обладают далеко не все компиляторы/рантаймы. Между тем совершенно не ясно в чем проблема использовать то же Set в императивном виде.

Можно, используют. В том же Окамле есть хэш-таблицы, для практических целей их очень даже можно применять.
Просто в идеале от побочных эффектов хотелось бы избавиться, каша-то заварена именно для того, чтобы программы имели формальную семантику, позволяли статический анализ, автоматическое распараллеливание, верификацию и т.д. В угоду практичности, т.е. применимости языка сейчас, жертвуют долгосрочными целями.
А то, что чистые ф. языки не распространены, это хорошо, т.к. не приходится комитетам по 10 лет заседать, чтобы добавить сборку мусора, например. Это тестовые стенды для всех передовых идей в области проектирования ЯП, которые к тому же некоторые умудряются успешно применять сейчас. Ни о каких догмах речь не идет. Цель — не запретить эффекты и состояние вообще, а найти подходящую модель для них.

VD>Физически получается так, что ради догм люди вынуждены получать не эффективные решения.

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

VD>Функциональный стиль мог бы стать хорошим дополнением в арсенале программиста, а сегодня он скорее является догмой и уделом едениц.

VD>Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".
Где эта догма высечена в камне, и зачем ее менять? Ведь в прогрессивных (на сегодня) ОКамле и Немерле так и сделано. Мало того, в Лиспе и стандартном МЛ то же самое — комбинируй функциональный стиль с императивным по самое не хочу. При должном умении программы получаются эффективные и выразительные, все довольны. Одно но: не все проблемы решены — автоматически параллелить нельзя, функции с побочными эффектами от чистых функций не отличить, и т.д и т.п. Поэтому исследования продолжаются, поэтому есть Хаскель, Clean и будут другие языки. Зачем с ними бороться?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.06 16:26
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Рубишь с плеча, ажно щепки летят во все стороны


Отнюдь. Просто излагаю что вижу.

LCR> Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.


Согласен. Причем тут ФЯ и их религия? Как видишь лямбды нефигово себя чувствуют в казалось бы насковзь императивных языках вроде C#. В С++ от них тоже никто бы не отказался.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.06 16:26
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>VladD2,


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


LCR>Называй как хочешь, но прозрачность ссылок — это свойство языка, то есть (абстрактной) нотации, в большой степени характена именно для ФЯ.


Дык и называю. И утверждаю, что "прозрачность ссылок" возводится в ФЯ в разряд догм.

LCR> Реализация может быть (и будет, ибо архитектура x86) императивной. Во многих случаях будет тот же mutable state, только за шторками. Поясню:...


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

Между тем, если состояние нужно, то нет смысла с ним боросться.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Философический вопрос про автоматический вывод типов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.02.06 18:55
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Там на Шарпе только мелкие и сравнительно автономные вещи типа панелей

C>свойств.

Значительно больше. А в VS2005 еще больше. Это я тебе как краевед говрю
... << RSDN@Home 1.2.0 alpha rev. 642 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[8]: Философический вопрос про автоматический вывод типов.
От: vdimas Россия  
Дата: 16.02.06 21:39
Оценка:
Здравствуйте, VladD2, Вы писали:

Странный у тебя был ответ. Я вообще-то не столько спорил с тобой, сколько соглашался в этих вопросах.

V>>Вообще-то, это все действительно догмы. Почему функциональные языки именно копируют объекты? Из-за банальной гарантии согласованного изменения значений. Таким образом они лишь гарантируют, что данный экземпляр значения существует лишь в текущем потоке исполнения и ему не грозит несогласованное изменение.


VD>А, ну, да. Это видимо догмы у меня о ФЯ. А не в ФЯ. Ясно. Всегда проще найти недостаток в оппоненте, чем в его словах.


Это ты не туда заехал. Я знаю, что догмы не у тебя, и лишь попытался обсуждать их причины (с тобой). Прочти этот абзац еще раз.

Ты упустил важный момент в моем посте. Я говорил еще о функциональной декомпозиции, которая существует наряду со структурной. У тебя ОЧЕНЬ БОЛЬШАЯ часть программы может быть выражена в том самом "чисто-функциональном" стиле. Но вот клиентом этой части может быть обычная императивная программа. И не надо говорить, что это уже будет не ФП. На определенном уровне декомпозиции у тебя может быть самый наичистейший ФП, а уж после того, как "чисто-функциональная" функция вернула результат, ей не все-равно ли, что с этим результатом делают?

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


VD>Нет уж. Многие программы не могут быть выражены в виде одного выражения как это постулируеют принцыпы ФП. Есть и объекты разделяемые разными потоками. Есть и глобальные сущьности. Есть и банально осязаемые вещи вроде форм.


Блин, ты о чем? Я попытался обсуждать, разложить по полочкам причины догм, а не спорить с тобой, вообще-то. со всем этим я и так согласен. А главная причина догм весомая — общее увеличение надежности и верифицируемости программ. И в своем предыдущем посте высказывал мнение, что такой подход надо использовать на всю катушку. Я ведь тоже считаю, что моделировать задачи реального мира чаще всего лучше именно с помощью такой пары абстракций как "экземпляр" и "состояние". Однако, при этом настаиваю на применении наработок из лагеря ФЯ.

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


Да, да и еще раз да. Я с тобой не спорил, повторю.


VD>К тому же я не вижу проблем в модифицирующих присвоениях. Они скорее мешают несбалансированной идеолгии нежели реально являеются проблемой сами.


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


VD>А не проще ли смотреть на все прогматично? ФЯ есть огромное затяжное исследование. В нем было сделано немало наработок. Многие из них были очень успешными. Так почему бы не совместить эти нароботки с наработками в других областях и не получить те самые гибриды. Далее остается только перестать фыркать и создать четкое видение использования такого гибрида. Разобраться для решения каких задач лучше подходит тот или иной подход и применять наиболее подходящие для решения конкретных подзадачь подходы.


Хм... Очевидно, ты тоже не столько споришь, сколько соглашаешься
Я вижу возможность гладкого совмещения в активном использовании функциональной декомпозиции.
Re[9]: Философический вопрос про автоматический вывод типов.
От: vdimas Россия  
Дата: 16.02.06 21:42
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>Рубишь с плеча, ажно щепки летят во все стороны Lambda-вычисления (и как следствия функциональные языки) — это раздел математики. Математика — точная наука.


Скорее, это единственный раздел, который УДАЛОСЬ хорошо формализовать. Опять же, за счет нескольких простых допущений, которые оказались верны для замыканий.
Re[9]: Философический вопрос про автоматический вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.06 02:01
Оценка:
Здравствуйте, Programmierer AG, Вы писали:

VD>>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.

PA>Устроим шустрик?

Можно. Быстрая сортировка устроит?

VD>>К тмоу же использование деревьев для Set-ов — это не лучшее решение. Тут нужно использовать хэш-таблицы.

PA>Эо уже вопрос десятый, ты говорил, что функциональные множества от рождения неэффективны. На C++, C# и Яве направо и налево применяются множества на деревьях.

В C# и Яве испльзуются в основном структуры на базе хэширования. Но это действительно дело десятое.

PA>Вызовы функций инлайнятся, когда это возможно. Засовывают переменную в регистр, когда это возможно. Заменяют хвостовую рекурсию циклом, когда это возможно. Аналогия просматривается?


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

PA>Можно, используют. В том же Окамле есть хэш-таблицы, для практических целей их очень даже можно применять.


Вот о том и речь. Только вот с ОКамлом есть небольшая проблемка. Императивный стиль на нем выглядит уж больно убого. А вот в Нэмерле очень даже ничего.

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


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

Вот такой расклад мне подходит. А во что бы то не стало использовать ФС я не хочу. Мне нужа гибкость, а не оптимальность по одному критерию.

PA>А то, что чистые ф. языки не распространены, это хорошо, т.к. не приходится комитетам по 10 лет заседать, чтобы добавить сборку мусора, например. Это тестовые стенды для всех передовых идей в области проектирования ЯП, которые к тому же некоторые умудряются успешно применять сейчас. Ни о каких догмах речь не идет. Цель — не запретить эффекты и состояние вообще, а найти подходящую модель для них.


Мне все же кажется, что чистые ФЯ — это порождения догм. Одно то, что они существуют очнь давно, но не смогли завоевать серьезной популярности настораживает.

VD>>Физически получается так, что ради догм люди вынуждены получать не эффективные решения.

PA>Никто никого не вынуждает, и догмы, повторюсь, нет. А чисто функциональные деревья и списки очень даже пригодны и эффективны для ряда задач.

Еще раз. Если пригодны, то можно и попользоваться. Вот только пригодны не всегда.

PA>Где эта догма высечена в камне, и зачем ее менять?


Почти в любом туториале по ФЯ. Причем обоснования почему модификация памяти это зло так и не приводится. Только заявление.

Точно так же никгде в статьях или других источниках по ФЯ не говориться почему в ФЯ все завязано на списки.

PA> Ведь в прогрессивных (на сегодня) ОКамле и Немерле так и сделано.


Не сказал бы что ОКамл прогрессивный на сегодня. Он конечно обладает достаточными императивными конструкциями, но вот уйти от "духа ФЯ" он так и не смок. Отсюда он крайне плохо будет восприниматься морем императивщиков. К тмоу же он имеет тучу других догм. Отсуствие перегрузки методов. Типизированные операторы. Отсутствие динамических типов. Весма странные и не ясные консрукции. В общем, это не тот язык который примут те кто сегодня сидит на С/Паскаль-подобых языках.

PA> Мало того, в Лиспе и стандартном МЛ то же самое — комбинируй функциональный стиль с императивным по самое не хочу.


Не совсем та. Императивный стиль на МЛ выглядит совсем ужасно.

Понимаш ли в чем дело. Нэмерл тем и подкупает, что являсь по суди ФЯ он предоставляет почти полную эмуляцию пмперативного C#. Так что я могу легко пересадить на него программиста привыкшего к С++/C# и потихоничку показывать ему это "другой мир". А на МЛ я вынужден засунуть его в полностью чуждую ему среду.

Ну, не поймет паттерн-матчинг 99% программистов. Погляди на реакцию на Нэмерел! Ведь большинство людей смотрит на него как на эдакий C# с макросами. И надо признать, что это тоже правильных взгляд, так как уже C# с макросами это больше чем C# без оных. Но главное, что это уже является побуждающим фатором для перехода. А там уже можно познакомиться с фичами Нэмерла как с "мелкими улучшениями". Ну, сначала вывод типов. Здорово ведь не писать не нужных деклараций? Потом паттернм матчинг. Далее глядишь силу функций высшего порядка народ осознает (которые в прочем уже доступны в C#, но на которую никто не обращает внимания) и силу рекурсии за оторую уже не нужно платить так дорого как в C#.

В общем, я вижу как такой язык можно внедрить в массы. А вот лоны МЛ и темболее Лиспа я вообще не верю, что можно в массы продвинуть. Это так и будет уделом фанатиков.

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


Должное умение — это тоже минус. Надо, чтобы люди без оного могли хотя бы повторить то что они уже далают на C# и ему подобных языках. А на МЛ-клонах это практически невозможно.

PA> Одно но: не все проблемы решены — автоматически параллелить нельзя, функции с побочными эффектами от чистых функций не отличить, и т.д и т.п. Поэтому исследования продолжаются, поэтому есть Хаскель, Clean и будут другие языки. Зачем с ними бороться?


Бороться ни с чем не надо. Есть и ладно. Я могу ошибаться, но ни один из ФЯ за исключением модерновых Скалы и Нэмерла в массы не пойдут (по описанным причинам).

А параллелизм в ФЯ пока что тоже мечат. Скорее на первых порах он будет достигнут спец-конструкциями котоыре опять таки проще ввести в язык через макросы. Ну, а там видно будет. Думаю пройдет еще не один виток исследований пока легкий параллелизм не станет достоянием масс.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Философический вопрос про автоматический вывод типов.
От: EXO Россия http://www.az.inural.ru
Дата: 17.02.06 04:53
Оценка:
Вот все же разумно пишешь, чего-ж тебя в других-то местах заносит?

Здравствуйте, VladD2, Вы писали:
VD>В том, что или они все же не чисто функциональные, или значительно менее эффективны нежели их императивные аналоги.

+1

VD>Физически получается так, что ради догм люди вынуждены получать не эффективные решения.


Уже осталось очень мало функциональных сред, которые столь строги в этом вопросе.
( Другое дело, что в большинстве сред есть возможность писать строго. Например, если требуется "доказуемый алгоритм", но никто же не заставляет... )
В том эе erlang-е например вообще есть "словари процессов", которые один в один "свойства" в терминах императивно-объектной модели. Когда есть желание — можно вообще в чисто объектной парадигме писать.
И в других системах такое есть. В том или ином виде.

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


+1

VD>Функциональный стиль мог бы стать хорошим дополнением в арсенале программиста, а сегодня он скорее является догмой и уделом едениц.


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

VD>Все что нужно изменить — это заменить догму "модификация памяти — это зло", на более мягкое "многие вещи можно эффективно решать без модификации памяти".


+1
Re[10]: Философический вопрос про автоматический вывод типов
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 17.02.06 06:23
Оценка: +1
VladD2,

VD>Ненадо мне пояснять. Я все и так понимаю.

Я стараюсь свои мысли выражать чётче, и не вижу здесь криминала. В твоём понимании материала я не сомневаюсь .

VD> Более того, я только за "низменяемость" если она ничего не стоит. Вот только в теории ФЯ все порят оговорки типа "во многих случаях". Не всегда можно действительно "за кулисами" превратить неэффективню операцию копирования в эффектинв модификации.

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

Но есть и хорошие новости. Например, _гарантируется_, что хвостовая рекурсия свернётся в цикл. Гарантируется, что в ситуациях типа
State1 = modify(State, Data).

State будет модифицирован. Так что здесь оборот "во многих случаях" можно заменить "всегда". Эти 2 случая очень распространены, поэтому ситуация в ФЯ не так плачевна, как кажется.

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

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

Короче, они друг друга никогда не поймут

VD>Между тем, если состояние нужно, то нет смысла с ним боросться.

Да, конечно.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.