Re[14]: BOOST, .NET, String.Split и производительность…
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 14:29
Оценка:
Здравствуйте, Курилка, Вы писали:

Сколько тебе надо дать дней бани чтобы ты проникся, что цитировать надо только то что необходимо для понимания твоего ответа?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 14:44
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Он на Руби пишет, в лучшем случае. А там как и в С++ ООП основное средство декомпозиции. Других практически нет. Одними лямбдами (блоками) сыт не будешь.


Ага, а тебе еще паттерн-матчинг добавили. Он рулит покруче ООП и лямб вместе взятых.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 14:46
Оценка:
Кстати, вопрос к тем, кто смайлики ставит: а что смешного?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: BOOST, .NET, String.Split и производительность…
От: WolfHound  
Дата: 20.09.06 14:47
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>По поводу наследования: в своих OpenSource проектах с ходу не нашел. А код из закрытых проектов не смотрел, т.к. результат все равно не смогу показать. Но раз или два пришлось делать наследование для функторов, чтобы общую функциональность в базовый класс поместить. Ну и простейший пример наследования для функторов -- наследование от std::unary_function .

Автор маньякЪ!
Мне лень разбиратся но у меня такое чувство что ты гдето нетак провел декомпозицию.
У меня никогда не возникало жилания сделать такие функторы.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: BOOST, .NET, String.Split и производительность…
От: FR  
Дата: 20.09.06 14:55
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>Кстати, вопрос к тем, кто смайлики ставит: а что смешного?


размер
Re[15]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 15:05
Оценка:
Здравствуйте, FR, Вы писали:

E>>Кстати, вопрос к тем, кто смайлики ставит: а что смешного?


FR>размер


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

К тому же для реальной (а не форумной пенисометрии) задачи объем получился весьма удовлетворительный: декларация функтора, тело operator() и тело вспомогательного метода, поотдельности занимают не более одной странички A4.

Так что это real life, смешного, как обычно, не много.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: BOOST, .NET, String.Split и производительность…
От: Denis2005 Россия  
Дата: 20.09.06 16:03
Оценка:
Здравствуйте, VladD2, Вы писали:

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


D>>Насчет черта лысого не уверен, но лямбда удалась на славу:


D>>
D>>void MyF1(vector<int>& vec, int s)
D>>{
D>>    transform(vec.begin(), vec.end(), vec.begin(), (s + _1));
D>>}
D>>


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


Они хороши только тем, что не потребовали расширения и без того очень 'широкого' языка.
Случаи чуть по сложнее решаются обычно функторами.

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


Невнятные сообщения об ошибках, это вполне нормальный случай, если библиотекой решается, то на, что изначально язык не был ориентирован.

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

VD>Вот как это будет выглядить не Немерле:
VD>
VD>transform.(s + _);
VD>

VD>"s + _" автоматом преобразуется в лямбду с одним параметром (никаких лишних скобок и хардкодед-имен вроде "_1" не нужно). Да и отсуствие идиотизма с begin()/end() разгружает код. В итоге получается, что писать функционально конечно на С++ можно, но неудобно, не всегда быстро, и очень громоздко.

Без лишних скобок: transform(vec.begin(), vec.end(), vec.begin(), s + _1);
А вот насчет begin()/end() не понял. Чем итераторы то не угодили?
Re[14]: BOOST, .NET, String.Split и производительность…
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 16:14
Оценка:
Здравствуйте, eao197, Вы писали:

VD>>Он на Руби пишет, в лучшем случае. А там как и в С++ ООП основное средство декомпозиции. Других практически нет. Одними лямбдами (блоками) сыт не будешь.


E>Ага, а тебе еще паттерн-матчинг добавили. Он рулит покруче ООП и лямб вместе взятых.


Он не то чтобы по круче, но в купе с алгебраическими типами во многих случая получается куда как выразительнее, чем без них. В купе же я просто имею больше средств для выражения. Ведь я могу выбирать из довольно широкого списка:
1. ООП (причем отлично реализованный, модульный, компонентный...).
2. Функции высшего порядка (ФВП).
3. Макросы (тяжелая артилерия).
4. Алгебраические типы и паттерн-матчинг.

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

В общем-то я тут согласен с Гапертоном — классы больше подходят для общего дизайна прилоежния. Для реализации ФВП и другие прибмабасы лучше подходят.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: BOOST, .NET, String.Split и производительность…
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 16:36
Оценка:
Здравствуйте, Denis2005, Вы писали:

D>Они хороши только тем, что не потребовали расширения и без того очень 'широкого' языка.


Что широкого в этом языке? Почему его нельзя целенаправлено рсширить действительно общепризнанно удобными возможностями? Зачем их эмулировать на коленке?

Хотя... мне уже по фигу. Меня этот вопрос занимал несколько лет назад. Теперь моя позиция очень простая. Горбатого могила исправит. Пусть гниет дальше.

D>Случаи чуть по сложнее решаются обычно функторами.


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

D>Невнятные сообщения об ошибках, это вполне нормальный случай,


Серьезно? Дочего можно довести себя самовнушением?!

D>если библиотекой решается, то на, что изначально язык не был ориентирован.


А зачем тогда делать это в библиотеке? Почему не расширить язык тем что многим так нужно? Ведь получится элегантнее, быстрее (код быстрее будет), удобнее и с нормальной диагностикой ошибок. Какова цель згонять популярный язык в угол?

D>Без лишних скобок: transform(vec.begin(), vec.end(), vec.begin(), s + _1);

D>А вот насчет begin()/end() не понял. Чем итераторы то не угодили?

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

Если в коде присуствует vec.begin() и vec.end() — это уже избыточный код. Ведь работа ведется со всем списком и отдельно указывать его голову так же глупо как на вопрос о расстоянии до объекта начинать давать его координаты и координаты место где ты находишся.

В общем, С++, точнее его создатели, нарушили один очень важный принцип KISS. И это его погубит. А пока он не умер, можно извлечь пользу для сбея и своей конторы перейдя на более продуктивный язык и набляюдая как туча ежиков колются, плачут но продолжают с упоением жрать это кактус.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: BOOST, .NET, String.Split и производительность…
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.09.06 16:51
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>Был бы это не функтор, а свободная функция или метод, размер бы не сильно уменьшился,


Это зависит... от разрабочика. Разумный разработчик произвел бы декомпозицию функций и получил бы ряд более простых фунций и собераемую из инх более сложную функцию.

Кстати, это как раз тот случай когда как раз функции высшего порядка неимоверно "рулят". ООП обычно не дает детализировать алгоритмы, так как оверхэд на описание классов и их методов превышает выигрышь от самой декомпозиции.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 17:01
Оценка: :)
Здравствуйте, VladD2, Вы писали:

E>>Был бы это не функтор, а свободная функция или метод, размер бы не сильно уменьшился,


VD>Это зависит... от разрабочика. Разумный разработчик произвел бы декомпозицию функций и получил бы ряд более простых фунций и собераемую из инх более сложную функцию.


Ага, и программы у таких разработчиков работают, если в них ошибок нет.

Ты посмотри на код, там нет ничего сложного -- один цикл и несколько if-ов. Объем создает только форматирование и комментарии.

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

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


Ой-ой-ой. Не поверю.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[15]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 17:05
Оценка: -1
Здравствуйте, VladD2, Вы писали:

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

VD>1. ООП (причем отлично реализованный, модульный, компонентный...).
VD>2. Функции высшего порядка (ФВП).
VD>3. Макросы (тяжелая артилерия).
VD>4. Алгебраические типы и паттерн-матчинг.

Можешь рассказать, какая помощь от макросов в обработке графовых структур?

VD>Причем последний пункт рельно по значемости я бы поставил на первое место.

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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: BOOST, .NET, String.Split и производительность…
От: Denis2005 Россия  
Дата: 20.09.06 17:05
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что широкого в этом языке? Почему его нельзя целенаправлено рсширить действительно общепризнанно удобными возможностями? Зачем их эмулировать на коленке?


VD>А зачем тогда делать это в библиотеке? Почему не расширить язык тем что многим так нужно? Ведь получится элегантнее, быстрее (код быстрее будет), удобнее и с нормальной диагностикой ошибок. Какова цель згонять популярный язык в угол?


Понять жизнь можно лишь оглядываясь назад, но жить-то приходится, смотря вперед. (C) Сёрен Кьеркегор
Была избрана такая политика, чтобы помаксимому давить на библиотеки, т.к. язык и без того слишком сложный и многими местами противоричивый.
Ты же знаешь, сколько времени нужно WG21 X3J16 чтобы принят то или иное решение, особенно если оно касается расширений.
А сколько пройдет когда реальными компиляторами будет поддерживаться введеное расширение?
Вот с библиотекой дела обстоят немного попроще, поэтому на них и делается основной упор.

VD>Хотя... мне уже по фигу. Меня этот вопрос занимал несколько лет назад. Теперь моя позиция очень простая. Горбатого могила исправит. Пусть гниет дальше.


'Горбатый' еще задаст жару молодым неокрепшим умам

D>>Случаи чуть по сложнее решаются обычно функторами.


VD>"Обычными"? Это где они слали обычными? Что-то я такого чуда природы в языках с функциями высшего прядка вообще не видел. И знаешь, мне кажется, что это потому, что фанкторы на фиг не упали.


Я сказал обычно, и применительно для C++. В C# 2.0 нормально обхожусь анонимными делегатами.

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

VD>Если в коде присуствует vec.begin() и vec.end() — это уже избыточный код. Ведь работа ведется со всем списком и отдельно указывать его голову так же глупо как на вопрос о расстоянии до объекта начинать давать его координаты и координаты место где ты находишся.

За всех говорит не стоит. Частенько бывает, что работа ведется с определенными фрагментами коллекции.
Хотя там где производительность особо не важна, можно и полными списками погонять.

VD>В общем, С++, точнее его создатели, нарушили один очень важный принцип KISS. И это его погубит. А пока он не умер, можно извлечь пользу для сбея и своей конторы перейдя на более продуктивный язык и набляюдая как туча ежиков колются, плачут но продолжают с упоением жрать это кактус.



Сам пишу пот .NET уже > 4 лет, если задача позволяет, поэтому про ежиков заканчивай.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: BOOST, .NET, String.Split и производительность…
От: McSeem2 США http://www.antigrain.com
Дата: 20.09.06 17:18
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

MS>>Так что язык здесь ни при чем вообще.


OE> C# вроде как под той же виндой тестируют с той же самой ntdll.dll


Разница в том, что C# не вызывает ntdll по isspace (или какой там аналог?). А сишная библиотека от MS по кой-то фиг вызывает (ну или вызывала, не знаю как оно сейчас).
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[18]: BOOST, .NET, String.Split и производительность…
От: WolfHound  
Дата: 20.09.06 17:45
Оценка: -1
Здравствуйте, eao197, Вы писали:

E>конструкциями типа std::for_each, std::find_if, std::transform и делать прозрачным более сложный код.

Это называется функции высшего порядка реализованные через зад автогеном.

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

E>Ой-ой-ой. Не поверю.
А зря. Только к проблеме нужно подходить комплексно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Наколенный вариант 8-летней давности
От: McSeem2 США http://www.antigrain.com
Дата: 20.09.06 18:06
Оценка: :)
Здравствуйте, Denis2005, Вы писали:

D>Компилятор: MS VC 8.0

D>Время работы: 20 секунд. (и это при полной оптимизации и отключенными проверками !?!)

D>Код на C#, .NET Framework:

D>Время работы: ~1 сек, при 10^7 итераций ~6 сек.


#include <stdio.h>
#include <string.h>
#include <time.h>

class tokenizer
{
public:
    enum sep_flag
    {
        single,
        multiple,
        whole_str
    };

    struct token
    {
        const char* ptr;
        unsigned    len;
    };

    tokenizer(const char* sep, 
              const char* trim=0,
              const char* quote="\"",
              char mask_chr='\\',
              sep_flag sf=multiple);

    void set_str(const char* str)
    {
        m_src_string = str; 
        m_start = 0;
    }

    token next_token();

private:
    
    // This function should actually be a template parameter
    static int check_chr(const char *str, char chr)
    {
        return chr == ' ';//int(strchr(str, chr));
    }

private:
    const char* m_src_string;
    int         m_start;
    const char* m_sep;
    const char* m_trim;
    const char* m_quote;
    char        m_mask_chr;
    unsigned    m_sep_len;
    sep_flag    m_sep_flag;
};

//-----------------------------------------------------------------------
tokenizer::tokenizer(const char* sep, 
                     const char* trim,
                     const char* quote,
                     char mask_chr,
                     sep_flag sf) :
    m_src_string(0),
    m_start(0),
    m_sep(sep),
    m_trim(trim),
    m_quote(quote),
    m_mask_chr(mask_chr),
    m_sep_len(sep ? strlen(sep) : 0),
    m_sep_flag(sep ? sf : single)
{
}


//-----------------------------------------------------------------------
tokenizer::token tokenizer::next_token()
{
    unsigned count = 0;
    char quote_chr = 0;
    token tok;

    tok.ptr = 0;
    tok.len = 0;
    if(m_src_string == 0 || m_start == -1) return tok;

    register const char *pstr = m_src_string + m_start;

    if(*pstr == 0) 
    {
        m_start = -1;
        return tok;
    }

    int sep_len = 1;
    if(m_sep_flag == whole_str) sep_len = m_sep_len;

    if(m_sep_flag == multiple)
    {
        while(*pstr && check_chr(m_sep, *pstr)) 
        {
            ++pstr;
            ++m_start;
        }
    }

    if(*pstr == 0) 
    {
        m_start = -1;
        return tok;
    }

    for(count = 0;; ++count) 
    {
        char c = *pstr;
        int found = 0;

        if(quote_chr == 0)
        {
            if(sep_len == 1)
            {
                found = check_chr(m_sep, c);
            }
            else
            {
                found = strncmp(m_sep, pstr, m_sep_len) == 0; 
            }
        }

        ++pstr;

        if(c == 0 || found) 
        {
            if(m_trim)
            {
                while(count && 
                        check_chr(m_trim, m_src_string[m_start]))
                {
                    ++m_start;
                    --count;
                }

                while(count && 
                        check_chr(m_trim, m_src_string[m_start + count - 1]))
                {
                    --count;
                }
            }

            tok.ptr = m_src_string + m_start;
            tok.len = count;

            m_start += count;
            if(c) 
            {
                m_start += sep_len;
                if(m_sep_flag == multiple)
                {
                    while(check_chr(m_sep, m_src_string[m_start])) 
                    {
                        ++m_start;
                    }
                }
            }
            break;
        }

        if(quote_chr == 0)
        {
            if(check_chr(m_quote, c)) 
            {
                quote_chr = c;
                continue;
            }
        }
        else
        {
            if(m_mask_chr && c == m_mask_chr)
            {
                if(*pstr) 
                {
                    ++count;
                    ++pstr;
                }
                continue; 
            }
            if(c == quote_chr) 
            {
                quote_chr = 0;
                continue;
            }
        }
    }
    return tok;
}


int main()
{
    tokenizer tokens(" ", "", "", 0, tokenizer::multiple);
    char dst[100];

    double tm1 = clock();
    for(int i = 0; i < 1000000; ++i)
    {
        tokens.set_str("123 345 asdf 23453 asdfas");
        for(;;)
        {
            tokenizer::token tok = tokens.next_token();
            if(tok.ptr == 0) break;
            if(tok.len)
            {
                // ATTN: DON'T DO THAT! Use std::vector<std::string> instead
                memcpy(dst, tok.ptr, tok.len); 
                dst[tok.len] = 0;
            }
        }
    }
    double tm2 = (clock() - tm1) / CLOCKS_PER_SEC;
    printf("%f\n", tm2);

    return 0;
}


Время: 0.328

IBM Thinkpad T43, Intel Centrino 2GHz
VC7.1
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[19]: BOOST, .NET, String.Split и производительность…
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.09.06 18:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

E>>конструкциями типа std::for_each, std::find_if, std::transform и делать прозрачным более сложный код.

WH>Это называется функции высшего порядка реализованные через зад автогеном.

Мне по барабану, как они называются вообще, а для моего конкретного случая это означало бы, что я не мог бы вызывать внутри алгоритма лямбды на 30-ть строк длиной, а передавал бы в аналог for_each функцию. И вызов:
std::find_if( c.begin(), c.end(), functor )

не сильно отличается от
c.find_if &functor

поскольку тело functor-а и его инициализация определены где-то в другом месте.

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

E>>Ой-ой-ой. Не поверю.
WH>А зря. Только к проблеме нужно подходить комплексно.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
pattern matching для питона :)
От: FR  
Дата: 20.09.06 19:47
Оценка: 39 (3)
Здравствуйте, eao197, Вы писали:

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


VD>>Он на Руби пишет, в лучшем случае. А там как и в С++ ООП основное средство декомпозиции. Других практически нет. Одними лямбдами (блоками) сыт не будешь.


E>Ага, а тебе еще паттерн-матчинг добавили. Он рулит покруче ООП и лямб вместе взятых.


Все-таки паттерн матчинг вещь в хозяйстве полезная, неплохо было бы если бы его ввели в питон, да и в руби бы не помешал, притом для ввода например в питон даже не надо больших уж затрат и ломки старого кода, достаточно одного ключевого слова. Ну а пока не ввели, я тут играюсь библиотечными методами, вот например такой эскизик сегодня нарисовал:
class when:
    patterns = []
    
    def __init__(self, expr):
        when.patterns.append(self)
        self.expr = expr

    def __call__(self, func):
        arg0 = tuple(getargspec(func)[0])
        self.func = func
        
        def _wrap(*args):
            d = dict(zip(arg0, args))
            
            for pattern in when.patterns:
                if pattern.func.__name__ == func.__name__ and eval(pattern.expr, globals(), d):
                    return pattern.func(*args)
                 
            raise TypeError("not find pattern: " + repr(d))
        
        return _wrap

использование:
@when("n < 2")
def fib(n):
    return 1

@when("n >= 2")
def fib(n):
    return fib(n - 1) + fib(n - 2)

print fib(8)


@when("a == 0")
def ack(a, b):
    return b + 1

@when("a != 0 and b == 0")
def ack(a, b):
    return ack( a - 1, 1 )

@when("True")
def ack(a, b):
    return ack( a - 1, ack( a, b - 1 ) );

print ack(3, 4)

Так что если очень хочется то и паттерн матчинг можно сделать
Re: pattern matching для питона :)
От: Programmierer AG  
Дата: 21.09.06 07:49
Оценка: +1
FR wrote:
> Так что если очень хочется то и паттерн матчинг можно сделать
Очень забавный фокус, хотя это не паттерн матчинг. Да, похоже на guards,
но в паттерн матчинге важнее выбор пути исполнения в одновременно со
связыванием переменных
, с разбором сложной структуры на части, а
этого в твоем примере ни разу нет.

<offtop>
А по каким словам надо гуглить, чтобы прочитать об этом трюке с @foobar?
Я тут для мелких скриптов начал Питон пробовать, но изучать некогда,
прыгать надо .
</foobar>
Posted via RSDN NNTP Server 2.0
Re[2]: pattern matching для питона :)
От: FR  
Дата: 21.09.06 08:15
Оценка: 7 (1)
Здравствуйте, Programmierer AG, Вы писали:

PA>FR wrote:

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

Угу это скорее ближе к мультиметодам, но упрощает решение тех же задач что паттерн матчинг.
При желании можно и связывание переменных добавить.
А струкуры и сейчас вполне разбираются, аргументом может быть любой логический предикат, при его истиности вызывается связанная функция
@when("isinstance(x, basestring)")
def my_print(x):
    print '<' + x + '>'
       
@when("isinstance(x, list)")
def my_print(x):
    print "["
    for i in x:
        my_print(i)
    print "]"
    
@when("True")
def my_print(x):
    print x


PA><offtop>

PA>А по каким словам надо гуглить, чтобы прочитать об этом трюке с @foobar?
PA>Я тут для мелких скриптов начал Питон пробовать, но изучать некогда,
PA>прыгать надо .
PA></foobar>

По слову decorator.
http://www.python.org/peps/pep-0318.html
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.