Заблокирован
|
|
1 | |
Clojure Мультидиспетчеризация не по типам15.03.2017, 22:48. Показов 2200. Ответов 26
Метки нет (Все метки)
что то я везде встречаю примеры мультидиспетчеризаци по типам. А как в лиспе диспетчеризовать не по типам, а по друзим вещам, по слотам, например?
Как будет выглядеть на лисповских мультиметодах аналог вот такого вот кода? Код
A := Object clone do( a := 0 accept := method(visitor, visitor doA(self)) ) B := Object clone do( b := 0 accept := method(visitor, visitor doB(self)) ) Visitor := Object clone do( doA := method(acceptor, acceptor a = acceptor a + 1) doB := method(acceptor, acceptor b = acceptor b + 1) ) a := A clone b := B clone visitor := Visitor clone list(a, b) foreach(acceptor, acceptor accept(visitor)) writeln(a a, b b) #>>>>11
0
|
15.03.2017, 22:48 | |
Ответы с готовыми решениями:
26
Мультидиспетчеризация и полиморфизм Мультидиспетчеризация в Лиспе Вопрос по типам вопрос по типам Си |
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
16.03.2017, 18:54 | 21 |
Сделайте другой объект по имени "spaceship", не копипастьте в него визитора из bar и покажите, что напечатает foo collide(qux). Если не "first object is asteroid", то нет никакой диспетчеризации по именам.
Почему же? Вы конкретно для baz-а написали метод, я тоже. Всё честно.
0
|
Заблокирован
|
|
16.03.2017, 19:04 [ТС] | 22 |
он напечатает дефолтный визитор, который наследуеет от SpaсeObject. Это никакого отношения к делу вообще не имеет.
В Io классы ничем не отличаются от объектов. Короче, не уводите тему в сторону. Диспетчеризуется все в зависимости от свойства name, никакой проверки на эквивалентность объектов там нет. Если вас так заели классы, то вот вам с классами код Код
SpaceObject := Object clone do( name ::= nil collide := method( call evalArgs foreach(visitor, visitor multyMethod(self)) ) multyMethod ::= method(spaceObject, writeln(spaceObject name .. " collide with " .. self name)) // default ) Foo := SpaceObject clone setName("asteroid") Bar := SpaceObject clone setName("spaceship") Baz := SpaceObject clone setName("planet") setMultyMethod( method(spaceObject, writeln("just another behavor for " .. spaceObject name .. " with planet")) ) foo := Foo clone bar := Bar clone baz := Baz clone foo collide(bar, baz) bar collide(foo, baz) baz collide(foo, bar) #>>>> asteroid collide with spaceship #>>>> just another behavor for asteroid with planet #>>>> spaceship collide with asteroid #>>>> just another behavor for spaceship with planet #>>>> planet collide with asteroid #>>>> planet collide with spaceship
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
16.03.2017, 19:13 | 23 |
А в чём тогда состоит смысл диспетчеризации по имени? Я думал, что для всех объектов по имени "spaceship" будет происходить что-то особенное. И вот вы создаёте объект по имени "spaceship", а он всего-навсего демонстрирует дефолтное поведение. Не ощущаю мощи.
Вы сами пишете только что, что новый объект с именем spaceship демонстрирует дефолтное поведение. Значит, от имени не зависит, потому что foo collide(bar) и foo collide(qux) дают разный результат, хотя bar и qux имеют одинаковые имена. Более того, строчка "first object is ..." будет печататься, только если второй объект - bar. Выходит, всё-таки по объектам диспетчеризация. Я не понял, что я от чего увожу, но если я захочу пользоваться спецификатором eql, я буду. А то может ещё вам на "базисе лиспа" писать, как заходящим студентам?
1
|
Заблокирован
|
|
16.03.2017, 19:18 [ТС] | 24 |
ну так в лисповской диспетчеризации тоже надо писать свой мультиметод на каждый случай, не? Если нет возможности сделать дефолтное пповедение, в случае отсутствия конфигурации, это только минус.
В общем, лисп этого не может, я так и подумал. Только по типам.
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
16.03.2017, 20:14 | 25 |
Я переписываю то, что вы мне даёте, без визиторов. И пока всё прекрасно работает без визиторов. Конечно, я не знаю тонкостей Io, я на ваш код смотрю как на псевдокод. Но если вас что-то не устраивает ― пишите словами. Не местоимениями. Пока вы пишете так: вываливаете псевдокод и говорите: «Сделайте то же самое, но не тоже самое». А потом: «Лисп ЭТО не умеет». А ЧТО сделать, и что ― ЭТО лисп неумеет ― неясно. Объясняйте русским языком. Мы же не гуру тут, нам ― русским языком.
Я примерно представляю, как сделать настоящую диспетчеризацию по именам, которой вы не продемонстрировали, без копипасты методов. Может, напишу.
0
|
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
||||||
16.03.2017, 21:16 | 27 | |||||
Грубо говоря, если надо диспетчеризовать по имени, надо имя тоже сделать аргументом генеричной функции. Например,
0
|
16.03.2017, 21:16 | |
16.03.2017, 21:16 | |
Помогаю со студенческими работами здесь
27
Помощь с примерами по типам ОС Вопрос по типам данных вопрос по синтаксису/типам неразбериха с типам VARCHAR Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |