Re[17]: Сильные стороны функционального программирования
От: Павел Леонов Россия icq: 138726397
Дата: 02.09.04 07:52
Оценка: +1
Здравствуйте, INTP_mihoshi, Вы писали:

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


VD>>И вообще, что неужели не ясно, что на ИЯ можно сделать все что угодно? В конце концов любой ФЯ в итоге выполняется на конкретном процессоре или генерирует код конкретного процессора, а любой машинный код — это по сути ИЯ.


INT>Подумалось, кстати, что в этом смысле ФОП похоже на ООП. Т.е. в функциональом стиле, как и в объектном, можно программировать почти на всех неспециализированных языках. А ОО или ФО языки — это просто языки, семантика и прагматика которых ориентированы на соответствующий подход. Кстати, ООП и ФОП похожи еще в том смысле, что первый является эффективнысм инструментом манипулирования и инкапсулирования с точки зрения структур данных, а второй — с точки зрения алгоритмов.


Другими словами, писать можно и ориентированно на подход, а потом транформировать в общий код. А в поиске сбалансированного языка победят наиболее эффективные подходы или их части.
Re[3]: Сильные стороны функционального программирования
От: mdw  
Дата: 02.09.04 08:12
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

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

mdw>>"Традиционно,это можно осуществить, сохраняя вывод F во временный файл", в смысле:
mdw>>Modul1.Out >> TempFile(Googol Mb) >> Modul2.In
mdw>>А каким эзотерическим способом (на обыкновенном процессоре и памяти) данные попадают из G в F в Фя?
mdw>>G — это кусок маш. кода, и F тоже. Через какой астрал кусок кода F получает (Googol Mb) из G, как это нельзя сделать "традиционно"?

mdw>>Сказка ложь, да в ней намек...

S>Смысл в том, что инициатива у последнего. Вместо того, чтобы вычислять данные, которые могут когда-то понадобиться, и складывать их в промежуточном виде (управление со стороны ввода), самый последний в цепочке запрашивает данные у предыдущих по мере необходимости (если она когда-нибудь возникнет).

Это также называется ленивыми вычислениями.

F запускается только тогда, когда G пытается прочитать некоторый ввод, и выполняется ровно столько, чтобы предоставить данные, который пытается читать G


Мне не очень понятно, почему это является особенностью именно FL(как противопоставление IL), и причем здесь вообще
L? Веб сервер исполняет работу и дает данные столько и тогда когда попросит клиент. Он не не делает ничего если нет
запроса "вот тебе аргументы (ссылка на файл) и дай мне 1024 ответа, и еще 1024, и еще..."
Мне кажется это обычное состояние дел, для разных програм и модулей внутри программ. Разве нет?
Чем в данном случае G(F) на Haskell отличается от G(F) на С (в свете lazy calculus etc)?

Кстати, здесь где-то было утверждение, что на вся программа FL состоит из функций, и сама есть функция.
А на С есть main(...) , и мне еще не приходилось писать код на C вне функций . Правда у функций есть побочные эффекты, что меняет дело. Последний абзац под флагом смайлика
Re[15]: Сильные стороны функционального программирования
От: Batiskaf Израиль http://www.mult.ru/
Дата: 02.09.04 08:28
Оценка: 9 (2) -1
Здравствуйте, VladD2, Вы писали:

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


B>>Кстати, может быть народу будет интересно глянуть уже сейчас на предполагаемый C# 3.0:

B>>Comega project

VD>Сдается мен, что этот ресерч вряд ли в таком виде сможет стать третьей версией Шарпа.

Ну вот послушай что говорит Anders Hejlsberg касательно предполагаемых фичеров в С# 3.0:
Anders Hejlsberg — Programming data in C# 3.0

Если посмотреть на то как это решено в Комеге:


    foreach( row in select cid, Sum(Freight) 
                    from c in DB.Customers 
                       left join o in DB.Orders on c.CustomerID == o.CustomerID
                    group by c.CustomerID as cid  
                    having Sum(o.Freight) > 1000.0M
                    order by Sum(Freight) 
                    ) {
       Console.WriteLine("{0,5}  {1,8}", row.cid, row[1]);
    }


да и просто на это!:

    // Use SQL Aggregates  everywhere!
    int[] series = {1, 2, 3, 4, 5, 6};    
    Console.WriteLine("\nSum of the series: {0}", Sum(series));



или такое!:

struct Address {
  struct{
    choice { string Street; int POBox; };
    string City;
    int? ZipCode;
    string Country;
  };
}

    public static void Main() {
      a = <Address>
            <Street>One Microsoft Way</Street>
            <City>Redmond</City>
            <Country>USA</Country>
          </Address>
          <Address>
            <POBox>100</POBox>
            <City>Redmond1</City>
            <Country>USA1</Country>
          </Address>;
      s = { yield return a.Street; yield return a.POBox ; yield return a.City; yield return a.ZipCode; yield return a.Country; };
      s.{Console.WriteLine(it);};
      // get Street
      string* b = a.Street;
      foreach(it in b){ Console.WriteLine("Street = {0}", it); };//энумерация всех улиц в неоднородной секвенции - в данном случае улица будет одна

      //get POBox
      int* c = a.POBox;
      foreach(it in c){ Console.WriteLine("POBox = {0}", it); };//по аналогии со Street
}



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


B>>Там кстати и стрим в роли возвращаемого значения функции применяется и ассинхронное выполнение методов, короче очень много элементов функциональных языков:


B>>
B>>  virtual string* Foo(){
B>>    yield return "Hello world1";
B>>    yield return "Hello world2";
B>>    yield return "Hello world3";  }
B>>


VD>Откровенно говоря использование синтаскиса указателя для таких целей просто маразм. Да и зачем нужны все эти извраты когда во второй версии Шарпа уже есть итераторы выплняющие такую же функцию. Вот код из того же R#-а:

VD>
VD>        /// <summary>
VD>        /// Возвращает энумератор позволяющий перебрать элементы коллеции 
VD>        /// в обратном порядке.
VD>        /// </summary>
VD>        public IEnumerator<T> GetReverseEnumerator()
VD>        {
VD>            for (int i = _len - 1; i >= 0; i--)
VD>                yield return _ary[i];
VD>        }
VD>


VD>Чем эти "стримы" будут отличаться от энумераторов я лично не понимаю.


Запись в Комеге значительно упрощается, а учитывая еще и особенности времени исполнения этой конструкции — установи комегу и отдибагируй, убедись что элемент в стриме вычисляется по ходу пьесы, в твоем же случае итерируется предварительно заполненная вычисленная последовательность, а что если для инициализации твоего массива не хватит памяти!? — то могу сказать что различия существенные.

B>> те же самые атрибуты,


VD>И с каких это пор атрибуты стали относиться к функциональным языкам?


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

B>> дженерики с темплейтами,


VD>Дженерики тоже к функциональным языкам отношения не имеют. Что-то ты уж больно много приписываешь ФЯ.

Дженерики ( в меньшей степени ), С++ темплейты в большей степени позволяют выразить алгоритм в обобщенной форме, декларативно, в конечном счете программист получает функциональный модуль, который более гибко адаптируется под конкретную предметную область. В конечном счете, если до конца придерживаться идеологии обобщенного программирования в С++, то решение задачи будет выглядеть следующим образом:

typedef Transport<HTTPProtocol, XMLContent> MyAppTransport;
typedef BizObjectContainer<StatelessStrategy, DBStorage> MyBizObjectContainer;
typedef BlaBlaAspect ...
...
...
typedef AppServerImpl< MyAppTransport, MyBizObjectContainer, ... > MyAppServerImpl;


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


B>> происходит обогащение декларативными средствами.


VD>Здорово! Т.е. декларативные средства == ФЯ?!

Да уж не императивного это точно!

B>> Да и в традиционном программинге в той же бизнес логике идеи FL проникают и туда, вот к примеру рассмотрим эту схему:


B>>BusinessEntities.ppt


B>>Если почитать спецификацию Business Entities модуля, то наиболее распространенное и рекомендуемое представление этого модуля это DataSet, и посмотрим на обмен стримами между функциональными блоками программы написанной на FL!


VD>В общем, Остапа понесло... (с) Приписываем все достижения человечества ФЯ, находим в библии зачатки ФЯ и рисуем радужную картину будущего в которой ничего кроме ФЯ не будет.


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


Architecture = PresentationLayer( ServiceLayer( BizLogicLayer( DataAccessLayer ) ) );


единственное чего не хватает в этой формуле это BusinessEntities, который является связующим звеном между каждым модулем, который позволяет упростить протокол общения сколько бы ни было сложных модулей на столько, что общение это можно выразить такой функциональной схемой, которая еще и понятна человеку. А теперь для того что бы прочувствовать разницу возьми к примеру код начинающего программиста на ВБ, где в методе Form_Load через мощный АДО выгребаются данные из базы, и там же это все байндится на добротно имплементированные кнопки со списками, со своими листенерами и пропертями, и попробуй выразить логику такой же простой схемой. И попробуй ему обьясни что он не прав, он ведь быстро достиг результата, благодаря тому что решил все самым императивным и строгим методом, не заботясь о том, что бы этой логикой воспользовались в других местах программы. И даже если он годик подучится и научится выделять уровни, это опять же не гарантирует что его архитектура запросто опишется таким простым способом, он наломает еще много дров что бы понять что уровни не должны обмениваться кучей интерфейсов которые нужно имплементировать, где то посылать ссылки на реализации интерфейсов и абстрактных классов, научить ответную сторону принимать эти ссылки, и прочие прочие условия взаимодействия уровней системы.


VD>Я вот вижу только несколько интересных идей которые несмненно со временем войдут в универсальные ИЯ. И вижу кучу проблем ФЯ котрые если не будут устранены, то не позволят ФЯ даже приблизиться к мэйнстриму.



B>>Теперь что касается мотивации по применению FL, опять же на мой взгляд. Если рассмотреть наше современное программирование, то чем постоянно занимается программист, это адаптацией структур данных из одного вида данных в другой, к примеру адаптация из данных в RDB в обьект нашего приложения, из обьекта приложения в визуальный интерфейс который описывает этот же обьект в терминах UI элементов, то есть речь идет об адаптации под любой вид ввода-вывода.


VD>Ввод-вывод был пройден в 70-ых годах прошлого века. После этого люди изобрели сложные компонетные/объектные системы позволяющие решать куда более сложные задачи. А ввод-вывод — это действительно примитивщина вроде командной строки.


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

Автоматизация визуализации данных
Автор: Batiskaf
Дата: 23.08.04


VD>ЗЫ


VD>В общем, уже порядком надоело слушать восхищенные возгласы на пустом месте. Давно пора делом доказывать приимущества, а не кричать про них в духе Остапа бендера на выступлении в клубе "Четырех коней".


А мне надоело заниматься рутиной, и я пытаюсь найти решение
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[4]: Сильные стороны функционального программирования
От: Курилка Россия http://kirya.narod.ru/
Дата: 02.09.04 08:56
Оценка:
Здравствуйте, mdw, Вы писали:

mdw>Мне не очень понятно, почему это является особенностью именно FL(как противопоставление IL), и причем здесь вообще

mdw>L? Веб сервер исполняет работу и дает данные столько и тогда когда попросит клиент. Он не не делает ничего если нет
mdw>запроса "вот тебе аргументы (ссылка на файл) и дай мне 1024 ответа, и еще 1024, и еще..."
mdw>Мне кажется это обычное состояние дел, для разных програм и модулей внутри программ. Разве нет?

Имхо — нет, вебсервер в любом случае находится в цикле проверки наличия запроса, т.е. идёт "пустой цикл", а при функциональном подходе никаких таких пустых циклов нет (если, конечно, самому что-либо подобное не написать) и вычислыяется то, что именно ты сказал вчислить... Думаю где-то так
Re[16]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 10:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


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


G>>И вот ты хочешь пробежаться по нему итератором. В "ленивой" реализации у тебя по крайней мере "ленивые" конструкторы элементов массива, так что элементы не будут на самом деле вычислены, пока ты не обратишься к ним через итератор. Вычисление будет отложено до момента чтения, который может вообще не случиться. Понимаешь разницу? Это позволяет тебе определять бесконечные (или ну очень большие) структуры данных, например.


G>>В строгой реализации все элементы контейнера будут вычислены сразу, а итератор — ну это просто итератор. Он никакой, ни ленивый, ни строгий. Это просто акцессор, интерфейс, способ доступа. А вот контейнер — строгий.

S>Тут надо просто понять, что первичен именно итератор. А вовсе не контейнер. Числа Фибоначчи — это никакой не массив и не список. Их можно только итерировать. И та статья об этом совершенно четко говорит.
Да ну? Так таки и не список? . А если так?
fib             = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]
process list     = process1 list + process2 list + process3 list + process4 list
process fib


У меня последовательность фибонначи при выполнении process fib вычисляются один раз. При этом совершенно не важно, сколько элементов списка обрабатывает каждая из функций processN. Функция process работает со списком. Числа Фибонначи — это список. Мой код состоит из трех строк.

Напиши код с такими же характеристиками на С#. Сравним сложность.
Re[5]: Сильные стороны функционального программирования
От: mdw  
Дата: 02.09.04 10:06
Оценка:
Здравствуйте, Курилка, Вы писали:

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


mdw>>Мне не очень понятно, почему это является особенностью именно FL(как противопоставление IL), и причем здесь вообще

mdw>>L? Веб сервер исполняет работу и дает данные столько и тогда когда попросит клиент. Он не не делает ничего если нет
mdw>>запроса "вот тебе аргументы (ссылка на файл) и дай мне 1024 ответа, и еще 1024, и еще..."
mdw>>Мне кажется это обычное состояние дел, для разных програм и модулей внутри программ. Разве нет?

К>Имхо — нет, вебсервер в любом случае находится в цикле проверки наличия запроса, т.е. идёт "пустой цикл", а при функциональном подходе никаких таких пустых циклов нет (если, конечно, самому что-либо подобное не написать) и вычислыяется то, что именно ты сказал вчислить... Думаю где-то так


Тут трудно спорить есть там цикл, или нет. Может, он, начиная с socket events, и вниз до железки, ждет пока придет фрайм в адаптер, а тот ждет пока поднимут 1 на ноге чипа. Все спят...

В общем случае, то что я имел ввиду, что при G(F), F ничего не делает(не производит и не передает данных) пока не вызвана G, вне зависимости на чем это было написано.
Может термин lazy calculus подразумевает еще какое-нибудь свойство, как например, и в С(IL) и Haskell(FL) вся программа состоит из функций, но в FL функции не имеют побочных эффектов, что в корне...
Re[6]: Сильные стороны функционального программирования
От: INTP_mihoshi Россия  
Дата: 02.09.04 10:23
Оценка:
Здравствуйте, mdw, Вы писали:

mdw>В общем случае, то что я имел ввиду, что при G(F), F ничего не делает(не производит и не передает данных) пока не вызвана G, вне зависимости на чем это было написано.

mdw>Может термин lazy calculus подразумевает еще какое-нибудь свойство, как например, и в С(IL) и Haskell(FL) вся программа состоит из функций, но в FL функции не имеют побочных эффектов, что в корне...

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

force x forces the suspension x and returns its result. If x has already been forced, Lazy.force x returns the same value again without recomputing it. If it raised an exception, the same exception is raised again. Raise Undefined if the forcing of x tries to force x itself recursively.

Пример ипользования

open Lazy

module Iter = 
    struct
        exception ExEnd
    
        type 'a t = Iter of 'a * 'a t Lazy.t | End
        
        let hd = function (Iter (hd, tl)) -> hd | End -> raise ExEnd
        let tl = function (Iter (hd, tl)) -> force tl | End -> raise ExEnd
        
        let rec map i f = 
            if i == End
                then End
                else Iter (f (hd i), lazy (map (tl i) f))

        let rec fold_rl i f x = 
            if i == End
                then x
                else f (fold_rl (tl i) f x) (hd i)
        
        let rec fold i f x = 
            if i == End
                then x
                else fold (tl i) f (f x (hd i)) 
                
        let rec nth i n = 
            if n==0
                then hd i 
                else nth (tl i) (n-1)

                
        let rec list l = if l==[] 
            then End 
            else Iter (List.hd l, lazy (list (List.tl l)))
        
        let rec from_random_access lenfunc getfunc ind =
            if ind >= lenfunc then End
            else Iter(getfunc ind, lazy (from_random_access lenfunc getfunc (ind+1)))
        
        let rec string s = from_random_access (String.length s) (String.get s) 0
        
    end


let si = Iter.string "Gaperton"

let g = Iter.fold si (fun s c -> String.concat "" [s; (String.make 1 (Char.uppercase c))]) ""


let it1 = Iter.list [10;20;0]

let it = Iter.map it1 (fun x -> x*2)

let s = Iter.fold it (fun x y -> x+y) 0

let s1 = Iter.nth it1 1
Re[18]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 10:53
Оценка:
Здравствуйте, VladD2, Вы писали:

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


G>>Хм, но в этом случае ты не получишь автоматического кэширования результатов (что ты имеешь бесплатно с ленивыми типами данных), это придеться делать руками.


VD>По сравнению с созданием класса реализующего итератор кэширвание просто фигня.

Не думал, что у вас создание такого класса представляет такую сложность . А у нас — вот так:
fib             = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]

Напиши такое на шарпе, можешь даже воспользоваться yield. Посмотрим, позволяет-ли он определать рекурсивные типы данных. Да, кстати, насчет "не думал" — это я слукавил. Я весьма хорошо представляю себе, как это будет выглядеть (правда, без yield)

VD>К тому же в этом самом классе ты данные и будешь кэшировать. Кэшировать то нужно один элемент.

Ответ неправильный. Иногда необходимо кэшировать предыдущие. Этот пример вычисляет фибонначи эффективно — сложность O(N), как раз благодаря кэшированию серии элементов (которое происходит абсолютно прозрачно). Синклеру приводил пример, когда кэшировать надо вообще все: http://www.rsdn.ru/Forum/Message.aspx?mid=790607&amp;only=1
Автор: Gaperton
Дата: 02.09.04
.

VD>А вот как раз второй Шарп решает вообще все проблемы, так как тот самый yield устраняет как необходимость кэширования, так и создания рабочего класса.

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

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

G>>В общем, сделать "ленивый" контейнер на C# можно, но надо смотреть в оба. Как бы потом не получилось в духе "я тебя породил, я тебя и убью".

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

К барьеру. Напиши код на С#, который имеет такую же характеристику, как приведенный код для фибонначи. А мы посмотрим, где проще ошибиться. Обрати внимание, что если я напишу
process1( fib ) + process2( fib ) + process3( fib )

то числа фибонначи все равно вычисляются один раз, а не три.
Re[3]: Сильные стороны функционального программирования
От: INTP_mihoshi Россия  
Дата: 02.09.04 10:56
Оценка: 2 (1)
Здравствуйте, Gaperton, Вы писали:

G>Да... Тут еще про ядерный реактор пример приводили, типа конечный автомат на ФЯ невозможно сделать. Называется, не бросайте меня в терновый куст. Так вот, мне лично было бы спокойнее, если бы управляющая программа этого реактора целиком была написана на ФЯ, и корректность ключевых модулей была-бы доказана . Я уже насмотрелся на прелести программирования "с помощью эффекта" за последние 10 лет, достало. А как вам — не знаю.


Кстати о реакторах...

Several large French corporations develop significant industrial projects in Objective Caml, including France T&#233;l&#233;com, Dassault, and CEA (<b>Commissariat &#224; l'&#201;nergie Atomique</b>).
Re[17]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 10:56
Оценка: +3
Здравствуйте, VladD2, Вы писали:

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


G>>Хотя, чтобы добиться такого же эффекта, ты на самом деле можешь фактически обойтись без контейнера, но заставить объект выглядеть снаружи как контейнер. Согласен, в этом смысле итераторы "ленивые".


VD>Да. Долго же до тебя это доходило.


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

Ты уверен, что я до этой мысли додуматься не мог, а не до того, что Синклер понимает под "ленивостью" итератора?
Кстати, почему ты объясняешь мне после того, как я додумался, а не до? Сейчас объяснять уже ничего не надо
Re[16]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 11:34
Оценка: 16 (3) +2 :)
Здравствуйте, VladD2, Вы писали:

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


VD>Блин. Ты по русски не понимашь?

Сделай сам себе замечание, ок?

VD>Или просто не хочешь поверить в то, что ленивые вычисления в ИЯ делаются как два палца об асфальт?

Конечно я не хочу в это поверить. Это не религия, а инженерное жело. У нас в предыдущем проекте вся подсистема обработки данных на С++ имеет ленивую семантику (обсчитывается то, что видно на экране, и потом кэшироется, и так в несколько слоев), и я за последние 6 лет имел возможность каждый день видеть, какой ценой это делается на ИЯ.

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

VD>Поверь итераторы не менее ленивы чем Хаскель.

Я последние 10 лет писал на ИЯ, и имею возможность сравнить сам. И вообще, зачем мне верить тебе на слово? Приведи пример, как подобает серьезным людям.

VD>И вообще, что неужели не ясно, что на ИЯ можно сделать все что угодно? В конце концов любой ФЯ в итоге выполняется на конкретном процессоре или генерирует код конкретного процессора, а любой машинный код — это по сути ИЯ.


Ясно конечно, за кого ты меня принимаешь? А тебе неужели не ясно, что "можно" и "целесообразно" разные вещи? На ассемблере можно сделать все, что угодно. Следует ли из этого, что на нем надо писать бухгалтерские программы?
Re[12]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 11:48
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


G>>Хочешь узнать истинную причину отсутствия аргументов? Мне просто не интересно с тобой трепаться. Се ля ви.

VD>Так не трепался бы.
Я и не треплюсь. В отличие от некоторых, я веду предметные разговоры.

VD>Неужели ты не понял, что своим трепом в данном случае ты еще немного расширил пропасть между ФЯ и мэйнстрим-программистами?

Нет, не понял. Отвечали двадцать раз уже, приходится повторять одно и тоже. Надоело.

Если пропасть состоит в том, что мэйнстрим-программистов интересует только то, что использует МС — то ее не увеличишь и не уменьшишь разговорами. И с такими людьми, которые не слушая аргументов долдонят одно и тоже, мне разговаривать не интересно, пусть думают что хотят.
Re[10]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 11:58
Оценка:
Здравствуйте, VladD2, Вы писали:

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


G>>Ты понятия не имеешь что такое ФЯ,

VD>Да потому что ты понятие не имешь что такое экономика. А он как раз говорил тут о ФЯ не как о языках программирования, а как о товаре и инструменте на ранке.
Ах, так это была тонкая экономическая аналитика? Ну тогда оставляю вас и дальше рассуждать об "экономике". Напоминаю, может кто забыл — я веду беседу о ФЯ.

VD>И вы показали полное незнание в данном вопросе и так и не дали внятного и разумного ответа на его вопрос. Причем лично мне совершенно ясно почему. Потому что ответ вам не выгоден.

То что тебе всегда все ясно, ни для кого не секрет. Завидую, жить легко наверно.
А ответ на этот вопрос давался трижды немного выше по ветке. Вы его игнорируете, потому что ответ вам не выгоден.
Re[17]: Сильные стороны функционального программирования
От: Sergey Россия  
Дата: 02.09.04 12:04
Оценка:
Hello, Gaperton!
You wrote on Thu, 02 Sep 2004 11:34:39 GMT:

G> Конечно я не хочу в это поверить. Это не религия, а инженерное

G> жело. У нас в предыдущем проекте вся подсистема обработки данных на С++
G> имеет ленивую семантику (обсчитывается то, что видно на экране, и потом
G> кэшироется, и так в несколько слоев), и я за последние 6 лет имел
G> возможность каждый день видеть, какой ценой это делается на ИЯ.

G> Так вот что я тебе скажу, кроме чрезвычайной гемморойности реализации,

G> достают побочные эффекты, которые надо учитывать при любой модификации
G> проги. Напоминает "драконий покер" из книг Асприна — да, все работает
G> так, как написано, но! Если самый младший из играющих силит напротив
G> входа и сейчас второй день полнолуния — все тузы становятся девятками, а
G> дама треф играет как валет пик!

Воистину так. Я тоже однажды решил сэкономить чуть-чуть на спичках (лень
было расчитывать, когда надо вид обновлять, а когда нет) и завяз в
отложенных вычислениях по самые уши, когда код слегка разросся.

With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[11]: Сильные стороны функционального программирования
От: Batiskaf Израиль http://www.mult.ru/
Дата: 02.09.04 12:05
Оценка: 2 (2) +2
Здравствуйте, Gaperton, Вы писали:

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


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


G>>>Ты понятия не имеешь что такое ФЯ,

VD>>Да потому что ты понятие не имешь что такое экономика. А он как раз говорил тут о ФЯ не как о языках программирования, а как о товаре и инструменте на ранке.
G>Ах, так это была тонкая экономическая аналитика? Ну тогда оставляю вас и дальше рассуждать об "экономике". Напоминаю, может кто забыл — я веду беседу о ФЯ.

VD>>И вы показали полное незнание в данном вопросе и так и не дали внятного и разумного ответа на его вопрос. Причем лично мне совершенно ясно почему. Потому что ответ вам не выгоден.

G>То что тебе всегда все ясно, ни для кого не секрет. Завидую, жить легко наверно.
G>А ответ на этот вопрос давался трижды немного выше по ветке. Вы его игнорируете, потому что ответ вам не выгоден.

Ало, ну зачем собачиться, ну не желает кто то понимать, ну и не надо, главное что комьюнити уже сформировалось. Давай не выступай, Чистяков, новый форум открывай, надоело уже длинные треды перематывать, будем считать что вступительная речь на открытие нового форума уже прозвучала
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[6]: Сильные стороны функционального программирования
От: Gaperton http://gaperton.livejournal.com
Дата: 02.09.04 12:05
Оценка:
Здравствуйте, VladD2, Вы писали:

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


G>>Складские системы — одна из самых простых систем,


VD>И сколько ты их собрал за свою жизнь?

Штук 20, начиная от самых простых (маленький магазин), до достаточно сложных (магазин с полным набором торгового оборудования, оптовая торговля, производство). Примеры — Stentor, фабрика спортивных изделий Leco, издательский дом IST. Занимался этим три года, с 1997 по 1999. Еще вопросы?
Re[16]: Сильные стороны функционального программирования
От: Xentrax Россия http://www.lanovets.ru
Дата: 02.09.04 17:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>И вообще, что неужели не ясно, что на ИЯ можно сделать все что угодно? В конце концов любой ФЯ в итоге выполняется на конкретном процессоре или генерирует код конкретного процессора, а любой машинный код — это по сути ИЯ.


Безотносительно к теме спора, конкретно вот это высказывание напоминает споры C/С++/Pascal vs assembler несколько лет назад — "на ассемблере и макросах можно сделать все то же, что и на С++, даже лучше"
Re[10]: Сильные стороны функционального программирования
От: ON  
Дата: 02.09.04 17:39
Оценка: :)
From: VladD2 rsdn www.optim.ru/cs
>Точно Хаскеля.

Хаскель не хаскель, а какой смысл использовать интерпретатор если функции не конструировать динамически. Посмотрел я Word.exe, 10 мег, никаких следов оптимизации по объему не заметил, искал слова вроде defun, нашел много раз повторяющиеся одни и те же справочники, если в unicode посмотреть, там даже есть "Целую" и "Получателю сего"
Posted via RSDN NNTP Server 1.9 beta
Re[7]: Сильные стороны функционального программирования
От: mdw  
Дата: 02.09.04 19:06
Оценка:
Здравствуйте, INTP_mihoshi, Вы писали:

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


mdw>>В общем случае, то что я имел ввиду, что при G(F), F ничего не делает(не производит и не передает данных) пока не вызвана G, вне зависимости на чем это было написано.

mdw>>Может термин lazy calculus подразумевает еще какое-нибудь свойство, как например, и в С(IL) и Haskell(FL) вся программа состоит из функций, но в FL функции не имеют побочных эффектов, что в корне...

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


INT>force x forces the suspension x and returns its result. If x has already been forced, Lazy.force x returns the same value again without recomputing it. If it raised an exception, the same exception is raised again. Raise Undefined if the forcing of x tries to force x itself recursively.


INT>Пример ипользования

[skipped]
INT>

С OCaml или другими ФЯ, к сожалению, не знаком. А синтаксис, с налету, не очень привычен. Так что пример я не совсем понял.
Но судя по тексту из "доки по OCaml", это что-то вроде:

int f(int i)
{
    static int nLastArg = INV_VAL, nLastRes = INV_VAL;
    
    if (i == nLastArg)
        return nLastRes; //or rethrow exception, whatever

    ..... 
}


Disclaimer: догадываюсь, что это я чего-то не понимаю . Очень хотелось бы понять в чем фокус. То есть что в lazy calculus такого, что делает его возможным в ФЯ, и трудно воплотимым в ИЯ.
Re[8]: Сильные стороны функционального программирования
От: Batiskaf Израиль http://www.mult.ru/
Дата: 02.09.04 19:38
Оценка:
Здравствуйте, mdw, Вы писали:

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


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


mdw>>>В общем случае, то что я имел ввиду, что при G(F), F ничего не делает(не производит и не передает данных) пока не вызвана G, вне зависимости на чем это было написано.

mdw>>>Может термин lazy calculus подразумевает еще какое-нибудь свойство, как например, и в С(IL) и Haskell(FL) вся программа состоит из функций, но в FL функции не имеют побочных эффектов, что в корне...

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


INT>>force x forces the suspension x and returns its result. If x has already been forced, Lazy.force x returns the same value again without recomputing it. If it raised an exception, the same exception is raised again. Raise Undefined if the forcing of x tries to force x itself recursively.


INT>>Пример ипользования

mdw>[skipped]
INT>>

mdw>С OCaml или другими ФЯ, к сожалению, не знаком. А синтаксис, с налету, не очень привычен. Так что пример я не совсем понял.

mdw>Но судя по тексту из "доки по OCaml", это что-то вроде:

mdw>
mdw>int f(int i)
mdw>{
mdw>    static int nLastArg = INV_VAL, nLastRes = INV_VAL;
    
mdw>    if (i == nLastArg)
mdw>        return nLastRes; //or rethrow exception, whatever

mdw>    ..... 
mdw>}
mdw>


mdw>Disclaimer: догадываюсь, что это я чего-то не понимаю . Очень хотелось бы понять в чем фокус. То есть что в lazy calculus такого, что делает его возможным в ФЯ, и трудно воплотимым в ИЯ.


Можно поставить Comega, его синтаксис более привычен, и подибагировать как это все работает, вот к примеру такой код:


int* FromTo(int b, int e){
    for (i = b; i <= e; i++) 
       yield return i; 
  }

  foreach(int i in FromTo(0,10)) {
     Console.WriteLine(i);
  }


Comega реализует все на closure, то есть в foreach встраивается экземпляр функционального обьекта ( ты его увидишь в отладчике, да и в IL сборке тоже найдешь ), в инстансе которого сохраняется весь контекст метода, метод возвращает стрим, это как бы сиквенция, которая совместима с семантикой итерации, с той лишь разницей что содержимое этой сиквенции не вычисляется одним махом, как в традиционном C#, а запрашивается по мере необходимости, с каждой новой итерацией foreach будет передаваться управление в FromTo closure, и именно с того места, на котором прервали выполнения раньше, тоесть вычисляет следующее значение сиквенции, которое затем распечатывается. Вот посмотри еще другие примеры: Cw Overview
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.