April 28, 2010
Wed, 28 Apr 2010 13:22:53 -0400, bearophile wrote:

> BCS:
> 
>>Could you elaborate on what exactly the expression problem is?<
> 
> I am far from being an expert on such matters, I will do what I can to answer. It's not an esoteric problem, if you program with an OO language you have probably faced it sometime.

You failed to mention that the OOP solution is in many cases overly complex. When you don't need to subclass the car elements, a functional pattern matching happens to win - at least if the declarativeness of code matters. The implementation can also use jump tables so it becomes faster than double dispatch. Luckily D is never going to get algebraic data types so you can all stop reading this post right here.

data CarElement = Wheel Name
                | Engine
                | Body
                | Car [CarElement]

defaultCar = Car [ Wheel "front left"
                 , Wheel "front right"
                 , Wheel "back left"
                 , Wheel "back right"
                 , Body
                 , Engine
                 ]

makeVisitor f element = map f (case element of
   Car elements = element : elements
   _            = [element]
)


visitor element = case element of
   Wheel name = "Visiting " +++ name +++ " wheel"
   Engine     = "Visiting engine"
   Body       = "Visiting body"
   Car _      = "Visiting car"

doVisitor element = case element of
   Wheel name = "Kicking my " +++ name +++ " wheel"
   Engine     = "Starting my engine"
   Body       = "Moving my body"
   Car _      = "Starting my car"

-- an example of usage:

-- makeVisitor visitor default
-- makeVisitor doVisitor default
April 28, 2010
On 04/28/2010 06:28 PM, retard wrote:
> Wed, 28 Apr 2010 13:22:53 -0400, bearophile wrote:
>
>> BCS:
>>
>>> Could you elaborate on what exactly the expression problem is?<
>>
>> I am far from being an expert on such matters, I will do what I can to
>> answer. It's not an esoteric problem, if you program with an OO language
>> you have probably faced it sometime.
>
> You failed to mention that the OOP solution is in many cases overly
> complex. When you don't need to subclass the car elements, a functional
> pattern matching happens to win - at least if the declarativeness of code
> matters. The implementation can also use jump tables so it becomes faster
> than double dispatch. Luckily D is never going to get algebraic data
> types so you can all stop reading this post right here.

I'm having trouble picturing the following scenario for a day in life.

* Wake up

* Shave

* Eat

* Drink coffee

* Go to work

* Do cool stuff

* Spend time reading and posting one bitter remark after another on a newsgroup dedicated to a language that I hate, I'm not required to use, I have no interest to see succeed, and I strongly believe breaks just about every single principle of good language design

* Back home

* Fun with girlfriend, wife, kids, TV, pet projects, etc.

* Eat

* Beer

* Sleep

One of these things is unlike the others!


Andrei
April 28, 2010
Wed, 28 Apr 2010 18:34:44 -0500, Andrei Alexandrescu wrote:

> On 04/28/2010 06:28 PM, retard wrote:
>> Wed, 28 Apr 2010 13:22:53 -0400, bearophile wrote:
>>
>>> BCS:
>>>
>>>> Could you elaborate on what exactly the expression problem is?<
>>>
>>> I am far from being an expert on such matters, I will do what I can to answer. It's not an esoteric problem, if you program with an OO language you have probably faced it sometime.
>>
>> You failed to mention that the OOP solution is in many cases overly complex. When you don't need to subclass the car elements, a functional pattern matching happens to win - at least if the declarativeness of code matters. The implementation can also use jump tables so it becomes faster than double dispatch. Luckily D is never going to get algebraic data types so you can all stop reading this post right here.
> 
> I'm having trouble picturing the following scenario for a day in life.
> 
> [snipped a very precise description of someone's life]
> 
> One of these things is unlike the others!
> 
> 
> Andrei

:) Sorry, but I actually have to use D. We long ago started some D projects and have to maintain them now (ok, this sounds worse than it really is - it's a joy compared to the xml bloat of j2ee and terribly bad design of php!). I also often fire up dmd to test some more or less trivial piece of code since I need the native codegen capabilities of the language so I really do have use for it. So, tyvm for the work so far, it has been really useful.

I also try to keep the amount of factual information on my posts above the level of bitterness. (I should probably refrain from posting at all if it annoys too much.) After all, there might be some hope that it educates the community as a large and puts some pressure on you to stop breaking the principles of good language design. Fwiw, it would calm some of the most demanding users of the language if there was a well documented process behind design decisions. I haven't heard any good arguments e.g. against algebraic data types other than "it confuses some novice C users".
April 29, 2010
Andrei Alexandrescu:
> I'm having trouble picturing the following scenario for a day in life.

After your experience with Loki, what do you think about double dispatch in external functions in D3?

Bye,
bearophile
April 29, 2010
On 04/28/2010 07:38 PM, bearophile wrote:
> Andrei Alexandrescu:
>> I'm having trouble picturing the following scenario for a day in
>> life.
>
> After your experience with Loki, what do you think about double
> dispatch in external functions in D3?

Good question. Statistically, I'd say very few people are interested in double dispatch. I've received reams of feedback from readers. Only a couple inquired or mentioned the double dispatch chapter at all. This is a bit odd because I think Loki's offering for double dispatch is comprehensive. It also had a few bugs in it that went unnoticed for a long time, which to me suggest very few actually needed that code.

Of course that's just a data point of sorts.

If we're to discuss double dispatch, I think we should first look at library solutions and at ways to improve the language to allow general solutions to categories of problems instead of cutesies like @virtual function parameters.

Above all, I think at this time we should go with improving the language definition and the quality of the compiler. There are quite a few strident notes in the current definition. Overloading is not taken care of properly, protection levels are underspecified and underimplemented, property syntax is broken, tuples are a mess. Also there's no 64-bit implementation. All that stuff is important and relatively urgent.


Andrei
April 29, 2010
Andrei Alexandrescu:

> Good question. Statistically, I'd say very few people are interested in double dispatch.

I see. I'd like to know what CLOS (CLisp) users too think about this.

(Generally if a feature become syntactically clean and nice, and it's written in the manual, surely more people can find the desire to use it. But this is just speculation.)


> If we're to discuss double dispatch, I think we should first look at library solutions and at ways to improve the language to allow general solutions to categories of problems instead of cutesies like @virtual function parameters.

In this case I agree that it's positive to first look for library solutions, and eventually, if seen fitting, think about moving something to the built-in features (see the answer I've written for Lutger).

Regarding the 'cutesies', I am irrevocably spoiled by Python and ShedSkin :-) My work on ShedSkin has shown me once and for all that a fast language and a very nice syntax are not incompatible things.

To give you a more focused answer, it's a matter of design balances. Tidy and specialized solutions are often nicer syntax-wise, and simpler to use. Such tidiness helps average-level programmers find the will to actually use them. Too much general solutions become like Rubik cubes that need a little too much assembly and brain to be used. But they can't be adapted to very different situations, etc. So in designing the language you must be balanced. Python shows that very well designed cutesies too can go a long way.


> Above all, I think at this time we should go with improving the language definition and the quality of the compiler.

You have noticed I have asked this question regarding D3. I agree that now there is enough work to do to produce a working D2 version.

You probably remember that recently I have shown in this newsgroup a list of little/tiny breaking changes (from some of my Bugzilla reports) to be discussed/addressed/fixed that I believe can be useful/necessary to create a good D2 implementation. They are surely more urgent than double dispatch. Despite this, I like to discuss here about all things.

Bye and thank you,
bearophile
April 29, 2010
On 2010-04-28 21:39:41 -0400, bearophile <bearophileHUGS@lycos.com> said:

> Andrei Alexandrescu:
> 
>> Good question. Statistically, I'd say very few people are interested in
>> double dispatch.
> 
> I see. I'd like to know what CLOS (CLisp) users too think about this.
> 
> (Generally if a feature become syntactically clean and nice, and it's written in the manual, surely more people can find the desire to use it. But this is just speculation.)

I think you're correct on that.

I'll point out that categories in Objective-C are used all the time and basically solve the same group of problem double dispatch does, but also have other uses. I think being able to attach your own extension methods to an existing class (methods you can override in subclass, or extensions to subclasses) is a much easier concept to grasp than double dispatch. The feature being used a lot in the standard library surely helps too.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

April 29, 2010
bearophile wrote:
> A short video about Clojure 1.2 Protocols, created to solve the expression problem (that D doesn't solve well yet), they are like fake multimetods because they are like single dispatch :-) (So they need just a virtual table, that the JavaVM can optimize well):
> 
> http://vimeo.com/11236603
> 
> By the way, you can see an example of the expression problem here, this is D code that solves one case of it:
> http://codepad.org/RPw6Kxu6
> 
> This is the same in Python with the multimethod (module inlined at the top), it's similar to CLisp CLOS solution:
> http://codepad.org/tWsYomoZ
> 
> Bye,
> bearophile

Has anyone tried to solve the expression problem by using opDispatch?
April 29, 2010
Michel Fortin:

>is a much easier concept to grasp than double dispatch.<

It's not hard to think about double dispatch, you can see it like a special case of function overload, where the language somehow allows you to overload on the base of the dynamic type of two objects. Things gets less easy to understand when you add inheritance into this mix.

Bye,
bearophile
April 29, 2010
On 04/29/2010 04:16 AM, bearophile wrote:
> Michel Fortin:
>
>> is a much easier concept to grasp than double dispatch.<
>
> It's not hard to think about double dispatch, you can see it like a special case of function overload, where the language somehow allows you to overload on the base of the dynamic type of two objects. Things gets less easy to understand when you add inheritance into this mix.

s/overload/override/g

Andrei