LINUX.ORG.RU

Слышал в Lisp с этим всё хорошо.

Насчет множественной в плюсах, джаве, лиспе не знаю, но например встроенной в эрланге нет, но можно легко реализовать на прикладном уровне. Через, например spawn|gen_server|gen_fsm|receive, благодаря легковесности процессов.

swwwfactory ★★
()

Паттерн «стратегия» ;) Например через хешмапу ))

А так можно в Scala через паттерн-матчинг, хотя будет немного не то.

vertexua ★★★★★
()
Ответ на: комментарий от staseg

А в рантайме как? Ну вот у тебя 2 параметра - оба имеют тип «указатель на базовый класс B» и что делать? Писать гигантский свитч с dynamic_cast?

nerdogeek
() автор топика
Ответ на: комментарий от nerdogeek

Потому я и сказал про оговорки.

В целом, ИМХО в С++ нужно думать по плюсячьи, а не пытаться повторять фишки других языков.

staseg ★★★★★
()
Ответ на: комментарий от yoghurt

Хм, всегда думал что визитор служит только для эмуляции двойной диспетчеризации
А как написать такой визитор, чтоб больше одного параметра принимал? Для двух например

nerdogeek
() автор топика
Ответ на: комментарий от vertexua

Так еще хешмапу надо заполнить как-то. Придется typeid выковыривать какой-то для всех возможных типов параметров мультиметода. Эх, грустно всё это. Не то что в лиспе.

nerdogeek
() автор топика
Ответ на: комментарий от staseg

В целом, ИМХО в С++ нужно думать по плюсячьи, а не пытаться повторять фишки других языков.

Да весь С++ --- это одна сплошная попытка повторить фишки других языков.

ugoday ★★★★★
()
Ответ на: комментарий от nerdogeek

Так еще хешмапу надо заполнить как-то.

А код то в лиспе надо писать как-то. Как система узнает какой код ты хочешь выполнять?

vertexua ★★★★★
()
Ответ на: комментарий от nerdogeek

interface Visitor {
    
    void visit(A1 a1, B1 b1);
    void visit(A1 a1, B2 b2);
    void visit(A2 a2, B2 b2);
    void visit(A2 a2, B1 b1);
}

interface VisitableA {
    
    void accept(Visitor visitor, VisitableB b);
}

interface VisitableB {
    
    void accept(Visitor visitor, A1 a1);
    void accept(Visitor visitor, A2 a2);
}

class A1 implements VisitableA {
    
    @Override
    public void accept(Visitor visitor, VisitableB b) {
        b.accept(visitor, this);
    }
}

class A2 implements VisitableA {
    
    @Override
    public void accept(Visitor visitor, VisitableB b) {
        b.accept(visitor, this);
    }
}

class B1 implements VisitableB {

    @Override
    public void accept(Visitor visitor, A1 a1) {
        visitor.visit(a1, this);
    }

    @Override
    public void accept(Visitor visitor, A2 a2) {
        visitor.visit(a2, this);
    }
}

class B2 implements VisitableB {

    @Override
    public void accept(Visitor visitor, A1 a1) {
        visitor.visit(a1, this);
    }

    @Override
    public void accept(Visitor visitor, A2 a2) {
        visitor.visit(a2, this);
    }
}

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

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Боюся спросить что будет для трёх.. параметров. Но ничего. Java/C++ программистов много, они справятся.

nerdogeek
() автор топика
Ответ на: комментарий от nerdogeek

Боюся спросить что будет для трёх.. параметров.

Не можешь сделать по аналогии?

Но ничего. Java/C++ программистов много, они справятся.

Ну вообще говоря это убогость С++. На Java через reflection такое делается очень просто и красиво.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

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

nerdogeek
() автор топика
Ответ на: комментарий от nerdogeek

Могу! Даже не смотря на экспоненциальный рост кода от числа параметров мультиметода.

Как будто в лиспе или где угодно не так.

Наверно в йаве есть даже фреймворк/либа на эту тему, раз всё так просто и красиво.

Есть и либы, можно и самому написать за часик, ничего сложного.

Legioner ★★★★★
()
Ответ на: комментарий от ugoday

Да весь С++ --- это одна сплошная попытка повторить фишки других языков.

Весь твой комментарий — неудачная попытка повторить успехи других троллей.

staseg ★★★★★
()

Через простую многомерную таблицу, через хеш-таблицу мапящую списки типов в обработчик. Про C++ см. последнюю главу книги Александрески.

crowbar
()
Ответ на: комментарий от Legioner

Как будто в лиспе или где угодно не так.

Лисперы! Друзья! Где же вы? Пропустите второй акт...

C++/Java VS. Lisp

nerdogeek
() автор топика
Ответ на: комментарий от deadlock

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

staseg ★★★★★
()
Последнее исправление: staseg (всего исправлений: 1)
Ответ на: комментарий от staseg

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

Это каких же возможностей? «метапрограммрование на шаблонах» что-ли? :) MPL ты называешь «лаконичными» возможностями?

deadlock
()
Ответ на: комментарий от deadlock

MPL я называю троллейбусом. Я много пишу на обоих языках, и твои ужимки кажутся мне просто смешными.

staseg ★★★★★
()
Ответ на: комментарий от staseg

MPL я называю троллейбусом.

А что не троллейбус? О каких тогда «достаточных возможностей для высокоуровневых абстракций, зачастую вполне лаконичных» идёт речь? :)

deadlock
()
Ответ на: комментарий от staseg

Речь идет, очевидно, о средствах языка. :) :) :)

И что это за средства такие? Заявление:

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

как минимум предполагает некие «возможности», которых нет в популярных языках, что делает таки C++ способным на определение «высокоуровневых абстракций», которые «зачастую вполне лаконичны»... Расскажи о них. Когда ещё встретишь такого великого человека, который просёк как C++, так и Lisp и точно знает кто «зацикленный, ограниченный и убогий» :)

deadlock
()
Ответ на: комментарий от deadlock

Ну вот ты и демонстрируешь свою зацикленность.

некие «возможности», которых нет в популярных языках, что делает таки C++ способным на определение «высокоуровневых абстракций»

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

staseg ★★★★★
()
Последнее исправление: staseg (всего исправлений: 1)
Ответ на: комментарий от deadlock

как минимум предполагает некие «возможности», которых нет в популярных языках, что делает таки C++ способным на определение «высокоуровневых абстракций», которые «зачастую вполне лаконичны»...

1. Класс как пространство имён

2. templates с инстанцированием по типам и целым значениям.

3. перегрузка операторов

monk ★★★★★
()
Ответ на: комментарий от monk

Изумительной крутизны возможности. Практически безграничны в планет построения «высокоуровневых абстракций».

deadlock
()
Ответ на: комментарий от deadlock

Практически безграничны в планет построения «высокоуровневых абстракций»

Можешь привести на любом другом языке аналог http://loki-lib.sourceforge.net/html/a00038.html с не худшими характеристиками производительности (все решения должны быть на стадии компиляции) и гибкостью (хотя бы EvictionPolicy и StatisticPolicy).

monk ★★★★★
()

В плюсах и яве сабж не нужен

buddhist ★★★★★
()
Ответ на: комментарий от monk

Во-первых, ну очень понятная дока. Там написано чуть менее чем нихуя. И документация по Loki полное говно. Что такое «EvictionPolicy и StatisticPolicy» там не написано (расскажи, что это или дай ссылку где можно почитать), зато написано:

template<class AbstractProduct, typename IdentifierType, typename CreatorParmTList = NullType, template< class > class EncapsulationPolicy = SimplePointer, class CreationPolicy = AlwaysCreate, template< typename, typename > class EvictionPolicy = EvictRandom, class StatisticPolicy = NoStatisticPolicy, template< typename, class > class FactoryErrorPolicy = DefaultFactoryError, class ObjVector = std::vector<AbstractProduct*>> class Loki::CachedFactory< AbstractProduct, IdentifierType, CreatorParmTList, EncapsulationPolicy, CreationPolicy, EvictionPolicy, StatisticPolicy, FactoryErrorPolicy, ObjVector >

Что как бы намекает нам на невероятную лаконичность и выразительность языка.

Во-вторых, все 3 пункта которые ты перечислил к этому не имеют никакого отношения. Тут как бы сразу видно, что это шаблонная магия. И даже беглого взгляда на исходик этой библиотеки достаточно, что бы понять, что большая часть исходиков сгенерирована внешним инструментарием. Очень удобное метапрограммрование. Ну просто уууочень!

deadlock
()
Ответ на: комментарий от deadlock

И документация по Loki полное говно. Что такое «EvictionPolicy и StatisticPolicy» там не написано (расскажи, что это или дай ссылку где можно почитать),

http://loki-lib.sourceforge.net/html/a00616.html#_details

EvictionPolicy — определяет объекты, которые надо выкинуть из кэша

StatisticPolicy — определяет метод сбора статистики по кэшу (сколько создано, вернуто из кэша/не из кэша, удалено, ...)

Что как бы намекает нам на невероятную лаконичность и выразительность языка.

Ну сэкономил автор на typedef'ах. А в целом вполне читабельно. В CLOS (например) тоже для каждого слота приходится писать (foo :initarg :foo :accessor foo) и лаконичней не делают (хотя макросы позволяют).

http://loki-lib.sourceforge.net/html/a00190.html пиздец, ребятки.

Можешь на любимом языке написать функцию с одним параметром, которая при получении функции с типом (int, int) -> int вызывала, её с параметрами 2 и 3, а при получении функции с типом (string)->int вызывала её с парметром «ok»? Хочу помотреть насколько лаконично у тебя получится.

Для указанной ссылки будет что-то вроде

template <typename F>
int foo(F f) { std::runtime_error("bad call foo") }

template <>
int foo(Functor<int, Seq(int, int)> f) { return f(2,3); }

template <>
int foo(Functor<int, Seq(string)> f) { return f("ok"); }

monk ★★★★★
()
Ответ на: комментарий от monk

функцию

Если функцию, а не функтор, то тут ни loki ни даже <functional> не нужны

int foo(int(&f)(int, int)) { return f(2, 3); }
int foo(int(&f)(std::string const&)) { return f("ok"); }

Вообще не придраться :)

Если замыкание, то

int foo(std::function<int(int, int)> const& f) { return f(2, 3); }
int foo(std::function<int(std::string const&)> const& f) { return f("ok"); }

Тут всякие претензии на ужасы внутри стандартных заголовков не принимаются, т.к. туда смотреть не полагается :)

З.Ы.

class Foo t where foo :: t -> Int
instance a ~ Int => Foo (a -> a -> a) where foo f = f 2 3
instance a ~ String => Foo (a -> Int) where foo f = f "ok"
quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от deadlock

Лол, прямо общелиспом запахло.

anonymous
()
Ответ на: комментарий от deadlock

Вообще-то так в любом языке. При написании кода на С нужно думать процедурами, в Haskell - фукционально. В Java - классами. Иначе твой код будет некрасиво громоздким и/или тормознутым. Если ты не обладаешь достаточной гибкостью мышления - это твоя проблема, а не языка. Не пиши на нем.

Aswed ★★★★★
()
21 февраля 2016 г.
Ответ на: комментарий от nerdogeek

А в рантайме как? Ну вот у тебя 2 параметра - оба имеют тип «указатель на базовый класс B» и что делать? Писать гигантский свитч с dynamic_cast?

Почитай Александреску, у него целая глава в книжке про мультиметоды.

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.