Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Functional

Boost , ,

Functional

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

    template <typename ScannerT>
    typename parser_result<self_t, ScannerT>::type
    parse(ScannerT const& scan) const;

Во всех аккаунтах это выглядит и очень похоже на Functional Programming. И действительно так. Дух - это, безусловно, применение функционального программирования в императивном домене C++. В Haskell, например, есть то, что называется парсерные комбинаторы, которые поразительно похожи на подход, принятый Духовно-парсерными функциями, которые состоят с использованием различных операторов для создания более высокого порядка парсерных функций, которые моделируют сверху вниз рекурсивный спусковой парсер. Эти умные люди Хаскелла делали это перед Духом.

Функциональные библиотеки программирования (или FP) набирают обороты в сообществе C++. Конечно, мы увидим больше FP в Духе сейчас и в будущем. На самом деле, если посмотреть более внимательно, даже стандартная библиотека C++ имеет вкус FP. Тщательно под ядром стандартной библиотеки C++ более пристальное внимание к STL дает нам представление о действительно существующей парадигме FP. Очевидно, что авторы STL знают и практикуют FP.

Semantic Actions in the FP Perspective

STL style FP

Более очевидное применение FP в стиле STL в Духе является семантическим действием. Что такое STL-стиль FP? Это в первую очередь использование функторов, которые могут быть составлены для формирования фукторов более высокого порядка.

Functors

A Function Object, or Functor is simply any object that can be called as if it is a function. An ordinary function is a function object, and so is a function pointer; more generally, so is an object of a class that defines operator().

Этот STL-стиль FP можно увидеть везде в наши дни. Следующий пример взят из руководства SGI Standard Template Library Programr's Guide:

    //  Computes sin(x)/(x + DBL_MIN) for each element of a range.
    transform(first, last, first,
              compose2(divides<double>(),
                       ptr_fun(sin),
                       bind2nd(plus<double>(), DBL_MIN)));

Really, this is just currying in FP terminology.

Currying

What is "currying", and where does it come from?

Currying has its origins in the mathematical study of functions. It was observed by Frege in 1893 that it suffices to restrict attention to functions of a single argument. For example, for any two parameter function f(x,y), there is a one parameter function f' such that f'(x) is a function that can be applied to y to give (f'(x))(y) = f (x,y). This corresponds to the well known fact that the sets (AxB -> C) and (A -> (B -> C)) are isomorphic, where "x" is cartesian product and "->" is function space. In functional programming, function application is denoted by juxtaposition, and assumed to associate to the left, so that the equation above becomes f' x y = f(x,y).

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

    expression =
        term
        >> *(   ('+' >> term)[make_op(plus<long>(), self.eval)]
            |   ('-' >> term)[make_op(minus<long>(), self.eval)]
            )
            ;

Полный исходный код может быть просмотрен здесь. Это часть распространения Духа.

Boost style FP

Повышение принимает парадигму FP дальше. Есть библиотеки, которые специально сосредоточены на функциональных объектах и программировании более высокого порядка.

Boost FP libraries
bind and mem_fn Generalized binders for function/object/pointers and member functions, from Peter Dimov
function Function object wrappers for deferred calls or callbacks, from Doug Gregor
functional Enhanced function object adaptors, from Mark Rodgers
lambda Define small unnamed function objects at the actual call site, and more, from Jaakko Järvi and Gary Powell
ref A utility library for passing references to generic functions, from Jaako Järvi, Peter Dimov, Doug Gregor, and Dave Abrahams

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

    class list_parser
    {
    public:
        typedef list_parser self_t;
        bool
        parse(char const* str)
        {
            return spirit::parse(str,
                //  Begin grammar
                (
                    real_p
                    [
                        bind(&self_t::add, this, _1)
                    ]
                    >> *(   ','
                            >>  real_p
                                [
                                    bind(&self_t::add, this, _1)
                                ]
                        )
                )
                ,
                //  End grammar
                space_p).full;
        }
        void
        add(double n)
        {
            v.push_back(n);
        }
        vector<double> v;
    };

Полный исходный код может быть просмотрен здесь. Это часть распространения Духа.

Этот парсер пересказывает список реальных чисел и хранит их в векторе<ДП>. Boost.bind создает Дух, соответствующий семантическому действию от функции list_parser add.

Lambda and Phoenix

Есть библиотека, написанная вами по-настоящему, по имени Phoenix. Хотя это официально не является частью распространения Духа, эта библиотека широко использовалась для экспериментов над передовыми методами FP на C++. Эта библиотека в значительной степени зависит от FC++ и усилится Lambda (BLL).

BLL

In as much as Phoenix is influenced by boost Lambda (BLL), Phoenix innovations such as local variables, local functions and adaptable closures, in turn influenced BLL. Currently, BLL is very similar to Phoenix. Most importantly, BLL incorporated Phoenix's adaptable closures. In the future, Spirit will fully support BLL.

Феникс позволяет писать семантические действия в интерактивном виде на C++ через лямбда (неназванная функция) выражения. Вот фрагмент из phoenix_calc.cpp Пример:

    expression
        =   term[expression.val = arg1]
            >> *(   ('+' >> term[expression.val += arg1])
                |   ('-' >> term[expression.val -= arg1])
                )
        ;
    term
        =   factor[term.val = arg1]
            >> *(   ('*' >> factor[term.val *= arg1])
                |   ('/' >> factor[term.val /= arg1])
                )
        ;
    factor
        =   ureal_p[factor.val = arg1]
        |   '(' >> expression[factor.val = arg1] >> ')'
        |   ('-' >> factor[factor.val = -arg1])
        |   ('+' >> factor[factor.val = arg1])
        ;

Полный исходный код может быть просмотрен здесь. Это часть распространения Духа.

Вам не нужно беспокоиться о деталях на данный момент. Здесь многое происходит, что нужно объяснить. Последующие главы будут просветительными.

Обратите внимание на использование выражений ламбды, таких как:

    expression.val += arg1
Lambda Expressions?

Lambda expressions are actually unnamed partially applied functions where placeholders (e.g. arg1, arg2) are provided in place of some of the arguments. The reason this is called a lambda expression is that traditionally, such placeholders are written using the Greek letter lambda .

где expression.val является переменной закрытия правила выражения (см. Closures). arg1 является заполнителем первого аргумента, что семантическое действие получит (см. Phoenix Place-holders). В Boost.Lambda (BLL) это соответствует _1.



Статья Functional раздела может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 05:09:50/0.0067858695983887/1