Live data from Hacker News

A polyglot's guide to multiple dispatch – part 3

eli.thegreenplace.net

1–10 of 19 posts

Re: A polyglot's guide to multiple dispatch – part 3

#2
I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most people on HN can see why that may not be a good attitude to have because of the larger implications of functional programming.

Method combination has an overarching theory behind it. My take is as follows: Methods are by definition associated with a set of constraints on the arguments. The constraints are, for the most part, specified by their class. Because classes form a mathematical lattice, we have the notion of "more and less specifically applicable methods" for a set of arguments, and so the aforementioned constraints can be ordered and usually the most specific method is called, as the article explains. But the key thing to notice here is that if we remove the notion of "more or less applicable", and replace it with just the notion of "applicable", then we can do some interesting things.

For a particular generic function (Lisp parlance for a method with unspecified constraints), and for a given set of arguments to the function, there is a set of applicable methods. How we arrange to execute these applicable methods, and how we arrange to use the results of the executions, is what constitutes method combination.

There are two trivial ways to arrange what gets executed. The popular way is to just execute the most specific only. The other trivial way is to just execute everything. Many kinds of non-default method combinations (like the LIST method combination) do this. Another one, which I find generally more useful, is the + method combination. (This sums all of the results of the applicable methods. One usual example is calculating prices with additive taxes.)

Many problems can be decomposed into one which sounds like the following: 1. Classify your objects into a (multiple-inheritance) class hierarchy. 2. Write down the behavior that is applicable to products of these objects.

If you can do 1 & 2, then these aspects of CLOS and method combination can solve your problem in a clean way.

* * *

There were a few nits I had with the article otherwise. What he calls "forms" are not forms. "Forms" are memory representations of the syntax. The syntax is called "symbolic expressions" or "S-expressions" or "S-exprs". An even more pedantic nit is that IF is not called a "special form", it is called a "special operator". The combination of a special operator and its arguments make a "special form". (But who cares. Even seasoned Lispers say "special form" for operators.)

Re: A polyglot's guide to multiple dispatch – part 3

#3
To provide an example of the utility of method combinations:

I wrote a project skeleton generator[0] whose functionality is provided by progn-composable plugins, implemented as mixin classes.

Every bit of functionality, like adding a README.md file to a project skeleton, adding a .gitignore file, adding stub unit tests, etc. is implemented as a mixin class. A full template inherits[1] all the mixins it needs.

There is a generic function, render-template[1], that takes a template, some options, and the target directory, and uses the progn method combination. Meaning: every method in the chain is called in succession, and each method adds its own thing to the generated project. The render-template method for the gitignore mixin adds a .gitignore file, for instance. When render template is called on an instance of a class that inherits a bunch of template mixins, it runs all of those mixins in addition to the render-template method of that class itself (if any).

In a sense, this is basically the entity-component pattern[3] implemented in the object system itself, with the caveat that you can't have "multiple instances" of the same component -- you can't inherit a class twice.

[0]: https://github.com/roswell/mystic

[1]: https://github.com/roswell/mystic/blob/2d0fd8e401d50893b4a15...

[2]: https://github.com/roswell/mystic/blob/2d0fd8e401d50893b4a15...

[3]: https://en.wikipedia.org/wiki/Entity_component_system

Re: A polyglot's guide to multiple dispatch – part 3

#4

I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most pe…

Indeed, where the article says:

"these features are too advanced to be useful in 99% of the cases"

I'm pretty sure when I wrote CLOS for a living (mind you, not recently) that I used :before, :around and :after rather more than that - they are a very natural and pretty simple extension to the basic method dispatch mechanism.

Re: A polyglot's guide to multiple dispatch – part 3

#6

I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most pe…

I wonder if anyone has a favorite example that uses method combinations, or auxiliary methods (:before, :after, :around), or something MOP related. Preferably one that is "in-the-wild" and not invented just to showcase the feature.

Re: A polyglot's guide to multiple dispatch – part 3

#7
Perl 6 makes calling sets of methods[0] easy as well:

    role Foo { multi method go { 1 } }
    role Bar { multi method go { 2 } }
    my $t = (class :: { }).new;

    $t does Foo;
    say $t.*go;  # (1)

    $t does Bar;
    say $t.*go;  # (2, 1)
[0]: https://design.perl6.org/S12.html#Calling_sets_of_methods

Re: A polyglot's guide to multiple dispatch – part 3

#8

I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most pe…

I wonder if anyone has a favorite example that uses method combinations, or auxiliary methods (:before, :after, :around), or something MOP related. Preferably one that is "in-the-wild" and not invented just to showcase the feature.

There are lots of examples of auxiliary methods. Here's an example of using around-methods to add slot-caching logic to a project for formula rendering: https://bitbucket.org/tarballs_are_good/formulador/src/63910...

Re: A polyglot's guide to multiple dispatch – part 3

#9

I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most pe…

s-expressions are a syntax for data. Lisp syntax is then layered on top of s-expressions.

Re: A polyglot's guide to multiple dispatch – part 3

#10

I mostly liked this article to show some of the basic features of CLOS, but was a little disappointed about the attitude toward the end. The attitude toward some of the more advanced features of CLOS like method combination reminds me of the attitude that some people have for functional programming. "Well, it's cool you can 'map' and 'reduce' a function across a list, but why not just use a for-loop?" I think most pe…

I wonder if anyone has a favorite example that uses method combinations, or auxiliary methods (:before, :after, :around), or something MOP related. Preferably one that is "in-the-wild" and not invented just to showcase the feature.

https://github.com/sellout/quid-pro-quo

Design by contract implemented via method combinations / MOP.

Post reply on HN