На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (6) « Первая ... 2 3 [4] 5 6  все  ( Перейти к последнему сообщению )  
> Erlang vs Haskel
    Цитата MyNameIsIgor @
    Ну, он же лишён деструктивных присваиваний. Да, функции, влияющие на глобальное окружение не отделены, потому исполняется всё последовательно. Но это явно не C.

    А кто запрещает не использовать деструктивные присваивания в Си? Но дело не в этом.

    Цитата MyNameIsIgor @
    Из этого следует, что любой язык, дающий возможность программисту управлять конкурентными процессами, а не делающий это автоматически, недалеко ушёл от C в части функциональщины

    Нет, из этого лишь следует, что в Эрланге внимание акцентировано на другом, а в сторону функциональщины он сделал лишь пару небольших шагов от Си.
      Цитата korvin @
      в сторону функциональщины он сделал лишь пару небольших шагов от Си

      Есть какие-то объективные мерки?
        Цитата korvin @
        а в сторону функциональщины он сделал лишь пару небольших шагов от Си.

        Есть мнение, что они шли не от Си :)
        Я тоже не понимаю, чем тебе erlang не угодил...

        Добавлено
        Цитата Qraizer @
        D_KEY, ну например, имея несколько, можно много, источников данных, например, файлов, по запросам отдавать их контент. Запросы могут приходить к разным источникам данных, а могут и к одному, контент запрашиваться из разных регионов источников, например, по разным смещениям от начала файлов, активных запросов может быть несколько в одно время, запросы на данные из некоего источника среднестатически запрашивают их последовательно расположенными порциями со среднестатически одинаковой периодичностью, но это не всегда так.
        Короче, тут больше над кодом клиента надо работать для получения объективных оценок кода сервера.

        Можно, в принципе, попробовать. Правда если внимательно посмотреть на тему, то придется сравнивать erlang и haskell :)

        korvin, ты как?

        Добавлено
        Цитата MyNameIsIgor @
        Цитата korvin @
        Нет. Но Эрланг не совсем в сторону функциональщины двигался же.

        А куда он двигался? Что тебя смущает? Отсутствие монад?

        Монады-то можно и прикрутить. Даже в C++ я препятствий не вижу к этому. Вот do-нотацию заменить сложнее :)
          Цитата D_KEY @
          Монады-то можно и прикрутить. Даже в C++ я препятствий не вижу к этому.

          Смысл монады не в интерфейсе, а в абстракции побочных эффектов. Хотя в C++ был бы полезен и интерфейс для, например, future.
          Цитата D_KEY @
          Вот do-нотацию заменить сложнее

          Так код на Erlang сам по себе и есть do-нотация :yes: korvin подтвердит.
            Цитата MyNameIsIgor @
            Смысл монады не в интерфейсе, а в абстракции побочных эффектов.

            Ну скорее в абстракции цепочки вычислений или даже абстракции связей в цепочке вычислений. Побочные эффекты есть не у всех монад, вроде даже большая часть вполне чистые. Да и IO "грязь" скрывает через RealWorld, т.е. строится через RealWorld -> (RealWorld, a).

            Впрочем, я, возможно, так и не понял монады, хотя вроде разобрался, как это дело работает :D
            С технической точки зрения там как-то все неэффективно выходит. Надо будет глянуть, оптимизирует ли их тот же ghc.
            Сообщение отредактировано: D_KEY -
              Нашел небольшой мануал по Хаскелю. Без пал-литры не разбересся! :wacko:

              Цитата D_KEY @
              Побочные эффекты есть не у всех монад,

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

              Добавлено
              Еще пробежался по мануалу Эрланга. Похоже korvin таки прав, Эрланг - в большей части декларативный язык, нежели функциональный. Не знаю как вам, мне показался более понятным по концепции. Сопоставления по образцу вообще порадовали - в духе регулярок Перла, правда с несколько другим применением. А вот однократное присваивание значений сразу приводит к мысли ожидаемой излишней траты памяти. Ну это так, по верхам.
                Цитата JoeUser @
                Вопрос: функция, использующая функцию с побочными эффектами, имеет побочные эффекты (если все остальное - чистые вычисления)?

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

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

                Эм. Функциональные языки - это декларативные языки. Как, например, и логические.

                Цитата
                Сопоставления по образцу вообще порадовали

                Они есть, наверное, во всех функциональных языках.

                Добавлено
                Могу попробовать накидать монады + реализацию монады IO на C++, если интересно. Но без do-нотации читать монадические выражения не так просто :)
                  Цитата D_KEY @
                  Эм. Функциональные языки - это декларативные языки. Как, например, и логические.

                  Ну да, эт я плаваю :rolleyes:

                  Добавлено
                  Цитата D_KEY @
                  Могу попробовать накидать монады + реализацию монады IO на C++, если интересно.

                  Интересно!

                  Добавлено
                  Цитата D_KEY @
                  Как, например, и логические.

                  Точно! Читал доку по Эрлангу, видел там вычисление функции как последовательность утверждений, де жа вю ... Пролог.
                    Пока только просто монады, IO потом попробую изобразить.
                    ExpandedWrap disabled
                      class Monad m where
                        (>>=) :: m a -> (a -> m b) -> m b
                        (>>) :: m a -> m b -> m b
                        return :: a -> m a
                        fail :: String -> m a


                    fail нам не нужен, остальное можно как-то так изобразить:

                    ExpandedWrap disabled
                      template<template<class ...> class M>
                      struct Monad {
                          // return :: a -> m a
                          template<typename T>
                          static auto ret(T a) -> M<T>;
                       
                          // bind :: m a -> (a -> m b) -> m b
                          template<typename T, typename U>
                          static auto bind(M<T>, std::function<M<U>(T)>) -> M<U>;
                      };

                    Хелперы/операторы:
                    ExpandedWrap disabled
                      // return :: a -> m a
                      template<template<class...> class M, typename T>
                      auto ret(T a) -> M<T>
                      {
                          return Monad<M>::ret(std::move(a));
                      }
                       
                      // (>>=) :: m a -> (a -> m b) -> m b
                      template<template<class...> class M, typename T, typename F>
                      auto operator >>= (M<T> ma, F fun) -> decltype(fun(std::declval<T>()))  // запутанно, но не знаю, как сделать лучше, чтобы работали лямбды
                      {
                          using R = decltype(fun(std::declval<T>()));
                          return Monad<M>::bind(ma, std::function<R(T)>(std::move(fun)));
                      }
                       
                      // (>>) :: m a -> m b -> m b
                      template<template<class...> class M, typename T, typename U>
                      auto operator >> (M<T> ma, M<U> mb) -> M<U>
                      {
                          return ma >>= [=](T){ return mb; };
                      }


                    Теперь нужно специализировать Monad<обертка>::ret и Monad<обертка>::bind.
                    Проверяем на простой монаде:

                    ExpandedWrap disabled
                      template<typename T>
                      struct value { // просто коробка со значением
                          value(T a)
                              : x(a)
                          {}
                       
                          T x;
                      };
                       
                      // специализируем ret
                      template<>
                      template<typename T>
                      auto Monad<value>::ret(T a) -> value<T>
                      {
                          // заворачиваем в коробку
                          return value<T>(a);
                      }
                       
                      // специализируем bind
                      template<>
                      template<typename T, typename U>
                      auto Monad<value>::bind(value<T> d, std::function<value<U>(T)> f) -> value<U>
                      {
                          // достаем значение, вызываем функцию, которая вернет следующую коробку
                          return f(d.x);
                      }


                    Проверяем на чем-нибудь простом:
                    ExpandedWrap disabled
                      auto succ(int x) -> value<int>
                      {
                          return ret<value>(x + 1);
                      }
                       
                      int main()
                      {
                          auto v = (ret<value>(10) >>= succ) >>= succ;
                       
                          std::cout << v.x << std::endl;
                      }

                    ExpandedWrap disabled
                      12


                    Вместо (ret<value>(10) >>= succ) >>= succ хотелось бы писать ret<value>(10) >>= succ >>= succ, но тут у C++ другая ассоциативность >>= чем в haskell. Можно заменить >>= на какой-нибудь другой оператор, на &, например.
                    ExpandedWrap disabled
                      ret<value>(10) & succ & succ


                    http://ideone.com/9AHtv1
                    Сообщение отредактировано: D_KEY -
                      Цитата D_KEY @
                      fail нам не нужен, остальное можно как-то так изобразить:

                      Наверное нужен ;) Я попробовал вместо 10 подставить 10.7f - отработало без ошибок и выдало 12 ... Хм ... подставил строку "abc" - отказалось собираться вообще. Значить fail надо как-то определять. Не?
                        Цитата JoeUser @
                        Наверное нужен ;)

                        Не, fail используется для других ситуаций.

                        Цитата
                        Я попробовал вместо 10 подставить 10.7f - отработало без ошибок и выдало 12

                        Ну так это к неявным преобразованиям в C++ претензии.

                        Цитата
                        подставил строку "abc" - отказалось собираться вообще

                        Так и должно быть.
                          Цитата D_KEY @
                          Не, fail используется для других ситуаций.

                          А каких?
                            Цитата JoeUser @
                            Цитата D_KEY @
                            Не, fail используется для других ситуаций.

                            А каких?

                            Он вызывается в случае ошибки сопоставления с образцом внутри монадического вычисления. Ну т.е. когда вы пытаетесь выполнить сопоставления с образцом вот в таком случае:
                            ExpandedWrap disabled
                              do
                                  ...
                                  (SomeConstructor x) <- someFun
                                  ...

                            а значение не соответствует образцу(в нашем случае someFun вернул значение с другим конструктором), то будет вызыван fail.
                            Не уверен, что понятно объяснил :)

                            Добавлено
                            Монаду IO реализую или вечером или завтра, сейчас надо работу работать :)
                              Цитата D_KEY @
                              Вместо (ret<value>(10) >>= succ) >>= succ хотелось бы писать ret<value>(10) >>= succ >>= succ, но тут у C++ другая ассоциативность >>= чем в haskell. Можно заменить >>= на какой-нибудь другой оператор, на &, например.
                              ExpandedWrap disabled
                                ret<value>(10) & succ & succ

                              Или на , :D

                              ExpandedWrap disabled
                                val x = (ret<value>(10), succ, succ, succ, succ);
                                Цитата D_KEY @
                                Он вызывается в случае ошибки сопоставления с образцом внутри монадического вычисления.

                                Покажи, плс, на самом коротеньком примере.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (6) « Первая ... 2 3 [4] 5 6  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0521 ]   [ 15 queries used ]   [ Generated: 19.04.24, 18:58 GMT ]