caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* C++/C# inheritance is bad?
@ 2009-01-16 15:18 Kuba Ober
  2009-01-16 15:58 ` [Caml-list] " Richard Jones
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Kuba Ober @ 2009-01-16 15:18 UTC (permalink / raw)
  To: caml-list

Yaron Minsky wrote a while ago that "When we first tried switching  
over from VB to C#,
one of the  most disturbing features of the language to the partners  
who read the code
was inheritance. They found it difficult to figure out which  
implementation
of a given method was being invoked from a given call point, and  
therefore
difficult to reason about the code.".

I was always puzzled about such an argument. Scott Meyers points
out at every opportunity that in C++ (and, by extension, in OO languages
in general), the class's interface is a contract that has to be upheld  
within
the inheritance tree. So if something is a Foo, then it must not  
matter that
it's an instance that derives 5 levels deep from Foo. If the code is  
written
such that a derived class breaks the contract, the code is written  
wrongly
and will cause no end of trouble. It's another story, of course, how
to uphold such contracts in your development environment: how much
can the compiler do, how much can the test harness do, how much
is done via static code analysis tools, etc.

Most importantly, inheritance has never meant to be a way to reduce the
amount of code. It's an incidental benefit, often cited as somehow the  
raison
d'etre of OO. If code reuse stands in the way of upholding the interface
contract, the contract wins in spite of code duplication. The best  
example,
perhaps, is the *widely abused* circle/ellipse inheritance. The fact  
that,
mathematically, a circle is an ellipse, does *not* mean that in OO  
language
you should derive a circle class from an ellipse class -- it makes no  
sense
at all if you think about it from the standpoint of interface  
contracts. In OO
world, a circle is *not* an ellipse. An ellipse has two radii, a  
circle doesn't,
that's where the story ends. The Wikipedia article about that problem is
amusing in the numerous examples they show that could supposedly
"fix" it somehow. I have not seen any decent, maintainable C++ code  
where
the Liskov's substitution principle was violated. I have violated it  
myself in
my early years of learning C++, and I have only regretted it.

So, when correctly applied, what's so disturbing about inheritance?  
You inherit
only where it makes sense, and if it makes sense then you don't care  
about
which particular method is called: it's supposed to be safe.

Cheers, Kuba

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 15:18 C++/C# inheritance is bad? Kuba Ober
@ 2009-01-16 15:58 ` Richard Jones
  2009-01-16 16:28   ` On the benefits of OO, Was: " Jan Kybic
  2009-01-16 18:27 ` Raoul Duke
  2009-01-17 13:27 ` Jon Harrop
  2 siblings, 1 reply; 22+ messages in thread
From: Richard Jones @ 2009-01-16 15:58 UTC (permalink / raw)
  To: Kuba Ober; +Cc: caml-list

On Fri, Jan 16, 2009 at 10:18:50AM -0500, Kuba Ober wrote:
[...]

OCaml?

> I was always puzzled about such an argument. Scott Meyers points out
> at every opportunity that in C++ (and, by extension, in OO languages
> in general), the class's interface is a contract that has to be
> upheld within the inheritance tree. So if something is a Foo, then
> it must not matter that it's an instance that derives 5 levels deep
> from Foo. If the code is written such that a derived class breaks
> the contract, the code is written wrongly and will cause no end of
> trouble. It's another story, of course, how to uphold such contracts
> in your development environment: how much can the compiler do, how
> much can the test harness do, how much is done via static code
> analysis tools, etc.

I guess that's precisely the point.  It's when you're at the sharp end
of a deadline and a debugger that you need to reason about the code.
Inheritence confuses the matter greatly because the code can be spread
over many files, and in fact it may not be possible to see the code
that really gets executed.  More dynamic IDEs can help here, but the
basic problem will remain as long as people keep using inheritence.

Functors suffer from the same problem by the way, particularly when
used extensively as in the source code for camlp4.

I have a more fundamental question: Is inheritence actually useful for
anything?  By which I mean, are there real world problems which are
solved elegantly with inheritence which are otherwise difficult to
solve?  I'm not sure I've seen many.  I have seen many very tortuous
class hierarchies though.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 22+ messages in thread

* On the benefits of OO, Was: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 15:58 ` [Caml-list] " Richard Jones
@ 2009-01-16 16:28   ` Jan Kybic
  2009-01-17 12:40     ` Oliver Bandel
  0 siblings, 1 reply; 22+ messages in thread
From: Jan Kybic @ 2009-01-16 16:28 UTC (permalink / raw)
  To: caml-list

> I have a more fundamental question: Is inheritence actually useful for
> anything?  By which I mean, are there real world problems which are
> solved elegantly with inheritence which are otherwise difficult to
> solve?  I'm not sure I've seen many.  I have seen many very tortuous
> class hierarchies though.
>

Some personal thoughts:

I think the OO methodology is good for creating reusable components
and maintaining a clean interface between them.

I develop complex algorithms which consist of many building blocks. 
Often, I need to try many variants before settling on a final
solution, sometimes there is not even any final solution - for each
subclass of a problem a different sub blocks might be appropriate.
It is a great time-saver if the building blocks can be swapped with as little
change in the code as possible.

The inheritance is then a convenient way of code reuse. 
Code reuse is important because it avoids code duplication. 
And code duplication is bad because it makes maintenance hard.

However, I am not using the OO features of Ocaml much, mainly because
of the speed penalty. 

Jan


-- 
-------------------------------------------------------------------------
Jan Kybic <kybic@fel.cvut.cz>                       tel. +420 2 2435 5721
http://cmp.felk.cvut.cz/~kybic                      ICQ 200569450


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 15:18 C++/C# inheritance is bad? Kuba Ober
  2009-01-16 15:58 ` [Caml-list] " Richard Jones
@ 2009-01-16 18:27 ` Raoul Duke
  2009-01-16 21:42   ` Kuba Ober
  2009-01-17 13:27 ` Jon Harrop
  2 siblings, 1 reply; 22+ messages in thread
From: Raoul Duke @ 2009-01-16 18:27 UTC (permalink / raw)
  To: caml-list

> the Liskov's substitution principle was violated. I have violated it myself
> ...
> So, when correctly applied, what's so disturbing about inheritance? You

i like these food-for-thought / throw-gasoline-on-the-fire articles
about the general subject:

http://alistair.cockburn.us/Constructive+deconstruction+of+subtyping

http://www.dbdebunk.com/page/page/626998.htm

sincerely.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 18:27 ` Raoul Duke
@ 2009-01-16 21:42   ` Kuba Ober
  2009-01-17  3:14     ` Sashan Govender
  0 siblings, 1 reply; 22+ messages in thread
From: Kuba Ober @ 2009-01-16 21:42 UTC (permalink / raw)
  To: caml-list


On Jan 16, 2009, at 1:27 PM, Raoul Duke wrote:

>> the Liskov's substitution principle was violated. I have violated  
>> it myself
>> ...
>> So, when correctly applied, what's so disturbing about inheritance?  
>> You
>
> i like these food-for-thought / throw-gasoline-on-the-fire articles
> about the general subject:
>
> http://alistair.cockburn.us/Constructive+deconstruction+of+subtyping

Good paper, but doesn't directly address the issue of good practice in  
C++-like
languages.

> http://www.dbdebunk.com/page/page/626998.htm

This is a great discussion, but it's purely theoretical. The author  
simply
says that OO model as implemented in C++ is quite deficient and a good
OO implementation should not have its drawbacks. Fine and dandy, but
when you *do* use C++/Java/C#, that's what you've got, and if you try
to abuse it, you deserve what you get ;)

I basically still hold that Yaron's original objection is baseless in  
face
of established good OO practice in C++/Java/C#/...

I do understand the limitations of the popular OO model, of course, and
the benefits of Jane Street choosing OCaml. I was merely trying to
understand what I don't understand about the popular OO model that
would have Yaron complain about not being able to tell which exact
method is being called... It, somehow, is not an issue for me, not in
well designed C++ codebases at least.

Cheers, Kuba


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 21:42   ` Kuba Ober
@ 2009-01-17  3:14     ` Sashan Govender
  2009-01-17 14:07       ` Kuba Ober
  0 siblings, 1 reply; 22+ messages in thread
From: Sashan Govender @ 2009-01-17  3:14 UTC (permalink / raw)
  To: Kuba Ober; +Cc: caml-list

>
> I basically still hold that Yaron's original objection is baseless in face
> of established good OO practice in C++/Java/C#/...
>
> I do understand the limitations of the popular OO model, of course, and
> the benefits of Jane Street choosing OCaml. I was merely trying to
> understand what I don't understand about the popular OO model that
> would have Yaron complain about not being able to tell which exact
> method is being called... It, somehow, is not an issue for me, not in
> well designed C++ codebases at least.

I thought he was talking about the effects of runtime polymorphism on
static code analysis. You can't tell which method is invoked if the
method is virtual.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: On the benefits of OO, Was: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 16:28   ` On the benefits of OO, Was: " Jan Kybic
@ 2009-01-17 12:40     ` Oliver Bandel
  0 siblings, 0 replies; 22+ messages in thread
From: Oliver Bandel @ 2009-01-17 12:40 UTC (permalink / raw)
  To: caml-list

Zitat von Jan Kybic <kybic@fel.cvut.cz>:

> > I have a more fundamental question: Is inheritence actually useful
> for
> > anything?  By which I mean, are there real world problems which are
> > solved elegantly with inheritence which are otherwise difficult to
> > solve?  I'm not sure I've seen many.  I have seen many very
> tortuous
> > class hierarchies though.
> >
>
> Some personal thoughts:
>
> I think the OO methodology is good for creating reusable components
> and maintaining a clean interface between them.
[...]

This also can be done with module system.
Functors for example can help a lot here.



>
> I develop complex algorithms which consist of many building blocks.
> Often, I need to try many variants before settling on a final
> solution, sometimes there is not even any final solution - for each
> subclass of a problem a different sub blocks might be appropriate.
> It is a great time-saver if the building blocks can be swapped with
> as little
> change in the code as possible.
[...]

Modules and Functors are very good for this task.
Just change the used module.

If you need a certain flexibility that modules can not offer,
for example, selecting certain implementations by user input,
both paradigms can be combined: use OO-style for the selection
of the seperate modules.


>
> The inheritance is then a convenient way of code reuse.

But it's very overrated.
Inheritance is the most obvious OO technique,
and the way, how people tries to convince
non-OO-programmers from the advantage of OO.
But there are many other OO mechanisms,
and ofteh it turns out that inheritance is used, where
other OO-technics would be much better.
With setting OO equal to inheritance, code will become
weid and clumsy. So the advantages of OO can't be turned
into advantages for the code.



> Code reuse is important because it avoids code duplication.
> And code duplication is bad because it makes maintenance hard.

Yes, and modules and functors are very good here.

>
> However, I am not using the OO features of Ocaml much, mainly because
> of the speed penalty.

If you don't use them, it looks to me that you don't need them.

If there really would be a need for OO in your code,
you would use it, otherwise your program could not run as intended.

So: you use OO for your own convenience (because you seem to be used to
it), even other techniques are sufficient for gaibning the goal.

I would use OO , when it is necessary, and not, if not.

OO paradigm does solve some problems of non-OO code.
But most of them can be done with modules and functional programming
techniques (higher order functions) also.

For many tasks OO is used like Bells-and-Whistles, and inheritance as an
addiction. This makes code not better. Using that techinques that help,
and not those, that are hype, will make code better.


Ciao,
   Oliver


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-16 15:18 C++/C# inheritance is bad? Kuba Ober
  2009-01-16 15:58 ` [Caml-list] " Richard Jones
  2009-01-16 18:27 ` Raoul Duke
@ 2009-01-17 13:27 ` Jon Harrop
  2009-01-17 14:35   ` Kuba Ober
  2 siblings, 1 reply; 22+ messages in thread
From: Jon Harrop @ 2009-01-17 13:27 UTC (permalink / raw)
  To: caml-list

On Friday 16 January 2009 15:18:50 Kuba Ober wrote:
> So, when correctly applied, what's so disturbing about inheritance?

Inheritance is disturbing because, in general, it cannot be applied correctly. 
That is why there are so many workarounds, many of which do not even exist in 
C++ like final methods, sealed classes, multimethods, extractors and so on. 
OO is not good in all circumstances and other tools can be preferable. IME, 
OO is only very rarely the best solution and it is only chosen so often 
because it is typically the only solution available (e.g. in C++ or Java).

> You inherit only where it makes sense, and if it makes sense then you don't
> care about which particular method is called: it's supposed to be safe.

Safety is quite different from easy of use, of course.

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17  3:14     ` Sashan Govender
@ 2009-01-17 14:07       ` Kuba Ober
  2009-01-18  6:24         ` Stefano Zacchiroli
  0 siblings, 1 reply; 22+ messages in thread
From: Kuba Ober @ 2009-01-17 14:07 UTC (permalink / raw)
  To: caml-list


On Jan 16, 2009, at 10:14 PM, Sashan Govender wrote:

>>
>> I basically still hold that Yaron's original objection is baseless  
>> in face
>> of established good OO practice in C++/Java/C#/...
>>
>> I do understand the limitations of the popular OO model, of course,  
>> and
>> the benefits of Jane Street choosing OCaml. I was merely trying to
>> understand what I don't understand about the popular OO model that
>> would have Yaron complain about not being able to tell which exact
>> method is being called... It, somehow, is not an issue for me, not in
>> well designed C++ codebases at least.
>
> I thought he was talking about the effects of runtime polymorphism on
> static code analysis. You can't tell which method is invoked if the
> method is virtual.

That's fine, because if your code is written well it doesn't matter at
all which one it is. All you care about is the interface and not the
particular implementation -- assuming that all implementations adhere
to the interface. Such adherence can be checked in isolation from
where the method is used. That's a separation of concerns in
code verification and is perhaps a good thing.

Cheers, Kuba


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 13:27 ` Jon Harrop
@ 2009-01-17 14:35   ` Kuba Ober
  2009-01-17 16:59     ` Jon Harrop
  0 siblings, 1 reply; 22+ messages in thread
From: Kuba Ober @ 2009-01-17 14:35 UTC (permalink / raw)
  To: caml-list


On Jan 17, 2009, at 8:27 AM, Jon Harrop wrote:

> On Friday 16 January 2009 15:18:50 Kuba Ober wrote:
>> So, when correctly applied, what's so disturbing about inheritance?
>
> Inheritance is disturbing because, in general, it cannot be applied  
> correctly.
> That is why there are so many workarounds, many of which do not even  
> exist in
> C++ like final methods, sealed classes, multimethods, extractors and  
> so on.
> OO is not good in all circumstances and other tools can be  
> preferable. IME,
> OO is only very rarely the best solution and it is only chosen so  
> often
> because it is typically the only solution available (e.g. in C++ or  
> Java).
>
>> You inherit only where it makes sense, and if it makes sense then  
>> you don't
>> care about which particular method is called: it's supposed to be  
>> safe.
>
> Safety is quite different from easy of use, of course.

I know I'm perhaps overusing Qt as an example, but it's just handy.
In Qt, the basic "instrumented" class is QObject. It implements  
retrospection,
signal/slot mechanism, etc. QWidget (a GUI building block) derives  
from it.
(and from a QPaintDevice, since you can paint on it).
Then, you have various widgets that derive from QWidget. Some of those
are abstract widgets (interfaces), like QAbstractButton, where a  
concrete
class faces the end user, like QPushButton.

It is quite a straightforward model -- as long as you think of it in  
terms of "ISA"
relationship between classes.

I wonder how such a hierarchy would be implemented in a natural way
in OCaml? By "natural" I mean being good practice and not feeling like  
a hack.
One should remember that users must extend the framework, so it should
be easy to extend say QWidget to create your own "class".

Cheers, Kuba


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 14:35   ` Kuba Ober
@ 2009-01-17 16:59     ` Jon Harrop
  2009-01-17 21:22       ` Kuba Ober
  2009-01-19 16:22       ` Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] Yoann Padioleau
  0 siblings, 2 replies; 22+ messages in thread
From: Jon Harrop @ 2009-01-17 16:59 UTC (permalink / raw)
  To: caml-list

On Saturday 17 January 2009 14:35:22 Kuba Ober wrote:
> I wonder how such a hierarchy would be implemented in a natural way
> in OCaml?

Assuming you stick with accepted wisdom, you would mimic the same effects 
using OCaml's object system, just as LablGTK does. However, you have picked 
the only pedagogical OO example: GUI widgets.

In contrast, metaprogramming is the pedagogical example for algebraic 
datatypes. There is almost no need for users to extend the abstract syntax 
tree but there is huge value in being able to rewrite expressions using 
pattern matching. There is an idiomatic OOP solution to this problem that 
involves visitor patterns and so forth but it is comparatively verbose, 
obfuscated and unmaintainable.

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 16:59     ` Jon Harrop
@ 2009-01-17 21:22       ` Kuba Ober
  2009-01-17 22:17         ` Jon Harrop
  2009-01-19 16:22       ` Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] Yoann Padioleau
  1 sibling, 1 reply; 22+ messages in thread
From: Kuba Ober @ 2009-01-17 21:22 UTC (permalink / raw)
  To: caml-list


On Jan 17, 2009, at 11:59 AM, Jon Harrop wrote:

> On Saturday 17 January 2009 14:35:22 Kuba Ober wrote:
>> I wonder how such a hierarchy would be implemented in a natural way
>> in OCaml?
>
> Assuming you stick with accepted wisdom, you would mimic the same  
> effects
> using OCaml's object system, just as LablGTK does. However, you have  
> picked
> the only pedagogical OO example: GUI widgets.

Perhaps that's where OO paradigm really shines. I'm very much against
shoehorning everything into it, of course.

> In contrast, metaprogramming is the pedagogical example for algebraic
> datatypes. There is almost no need for users to extend the abstract  
> syntax
> tree but there is huge value in being able to rewrite expressions  
> using
> pattern matching. There is an idiomatic OOP solution to this problem  
> that
> involves visitor patterns and so forth but it is comparatively  
> verbose,
> obfuscated and unmaintainable.

You've got me there -- I never liked the visitor pattern, and by  
extension
the event-based XML parsers written in C-like languages.

Cheers, Kuba


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 21:22       ` Kuba Ober
@ 2009-01-17 22:17         ` Jon Harrop
  2009-01-17 23:29           ` David Teller
  0 siblings, 1 reply; 22+ messages in thread
From: Jon Harrop @ 2009-01-17 22:17 UTC (permalink / raw)
  To: caml-list

On Saturday 17 January 2009 21:22:19 Kuba Ober wrote:
> On Jan 17, 2009, at 11:59 AM, Jon Harrop wrote:
> > On Saturday 17 January 2009 14:35:22 Kuba Ober wrote:
> >> I wonder how such a hierarchy would be implemented in a natural way
> >> in OCaml?
> >
> > Assuming you stick with accepted wisdom, you would mimic the same
> > effects
> > using OCaml's object system, just as LablGTK does. However, you have
> > picked
> > the only pedagogical OO example: GUI widgets.
>
> Perhaps that's where OO paradigm really shines. I'm very much against
> shoehorning everything into it, of course.

We've wrapped part of WPF in a functional shim for our F# for Visualization 
product and, even though it was originally intended for internal use only, 
our customers are loving using it themselves because it is vastly simpler and 
less error prone than trying to use WPF's own heavily-imperative but entirely 
thread unsafe OOP-based API directly.

Also, specifying callbacks and event handlers as first-class functions is 
obviously preferable to an OOP-based workaround.

> > In contrast, metaprogramming is the pedagogical example for algebraic
> > datatypes. There is almost no need for users to extend the abstract
> > syntax
> > tree but there is huge value in being able to rewrite expressions
> > using
> > pattern matching. There is an idiomatic OOP solution to this problem
> > that
> > involves visitor patterns and so forth but it is comparatively
> > verbose,
> > obfuscated and unmaintainable.
>
> You've got me there -- I never liked the visitor pattern, and by
> extension the event-based XML parsers written in C-like languages.

Oh yes. Java is utterly intolerable in that respect. I cannot believe how 
popular it became despite that...

Parallelism and concurrency are other examples where OOP sucks.

Cilk and Microsoft's TPL are the gold standards for parallel programming right 
now and both are build around concurrent work stealing queues of functions 
waiting to be applied. This works best for divide and conquer algorithms 
which, in turn, lend themselves to recursive functions. The reason being that 
older functions on a queue are more likely to be parent functions that will 
spawn many offspring, so when an idle core steals from the back of another 
core's queue it is likely to steal a parent function that will keep it busy 
for some time to come.

F#'s asynchronous workflows use monadic style to make concurrent programming 
easier.

Incidentally, Cilk looks like the ideal tool to write a parallel GC...

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 22:17         ` Jon Harrop
@ 2009-01-17 23:29           ` David Teller
  2009-01-17 23:49             ` Jon Harrop
  0 siblings, 1 reply; 22+ messages in thread
From: David Teller @ 2009-01-17 23:29 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

On Sat, 2009-01-17 at 22:17 +0000, Jon Harrop wrote:
> We've wrapped part of WPF in a functional shim for our F# for Visualization 
> product and, even though it was originally intended for internal use only, 
> our customers are loving using it themselves because it is vastly simpler and 
> less error prone than trying to use WPF's own heavily-imperative but entirely 
> thread unsafe OOP-based API directly.

Out of curiosity: is there a public documentation for your functional
API?

> Incidentally, Cilk looks like the ideal tool to write a parallel GC...

Mmmmhhh... Care to argument this? While I'd be glad to implement, say,
graph search or min-max/alpha-beta with Cilk, I don't quite see how a
concurrent GC would fit into the Cilk model.

Cheers,
 David

-- 
David Teller-Rajchenbach
 Security of Distributed Systems
  http://www.univ-orleans.fr/lifo/Members/David.Teller
   Latest News of French Research: System being liquidated. Researchers angry. 


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 23:29           ` David Teller
@ 2009-01-17 23:49             ` Jon Harrop
  0 siblings, 0 replies; 22+ messages in thread
From: Jon Harrop @ 2009-01-17 23:49 UTC (permalink / raw)
  To: caml-list

On Saturday 17 January 2009 23:29:06 David Teller wrote:
> On Sat, 2009-01-17 at 22:17 +0000, Jon Harrop wrote:
> > We've wrapped part of WPF in a functional shim for our F# for
> > Visualization product and, even though it was originally intended for
> > internal use only, our customers are loving using it themselves because
> > it is vastly simpler and less error prone than trying to use WPF's own
> > heavily-imperative but entirely thread unsafe OOP-based API directly.
>
> Out of curiosity: is there a public documentation for your functional
> API?

Sure thing:

http://www.ffconsultancy.com/products/fsharp_for_visualization/docs/namespaces.html

That reminds me, I need to update it for the latest release. Our Smoke Vector 
Graphics product for OCaml uses similar techniques but it is less evolved:

http://www.ffconsultancy.com/products/smoke_vector_graphics/

> > Incidentally, Cilk looks like the ideal tool to write a parallel GC...
>
> Mmmmhhh... Care to argument this? While I'd be glad to implement, say,
> graph search or min-max/alpha-beta with Cilk, I don't quite see how a
> concurrent GC would fit into the Cilk model.

Parallel, not concurrent. By parallel GC, I mean stop the world and call into 
code that traverses the heap using a parallelized algorithm. That would just 
be a simple recursive function in Cilk that is, of course, just graph 
traversal.

You are quite right that Cilk is not useful for writing a concurrent GC, where 
the mutator and GC use fine-grained concurrency to avoid global stalls.

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] C++/C# inheritance is bad?
  2009-01-17 14:07       ` Kuba Ober
@ 2009-01-18  6:24         ` Stefano Zacchiroli
  0 siblings, 0 replies; 22+ messages in thread
From: Stefano Zacchiroli @ 2009-01-18  6:24 UTC (permalink / raw)
  To: caml-list

On Sat, Jan 17, 2009 at 09:07:19AM -0500, Kuba Ober wrote:
>> I thought he was talking about the effects of runtime polymorphism on
>> static code analysis. You can't tell which method is invoked if the
>> method is virtual.
> That's fine, because if your code is written well it doesn't matter at
> all which one it is. All you care about is the interface and not the
> particular implementation -- assuming that all implementations adhere

It seems to me that you are implicitly assuming that the interface is
expressive enough to encode all the good properties you want your code
to obey to, while it is not the case, especially for mainstream OO
languages whose type systems are waaaaaaay too lightweight.

Hence, the reference to static analysis above was, AFAICT,
specifically meant to prove properties which are not encoded by the
method interfaces, and hence depend on the method implementations.

And precisely that you are screwed, because you need to know which
method is actually called, which is harder with ad-hoc polymorphism.


Somebody mentioned in this thread that the same problem has to be
faced with functors. That is true for the casual look at the code, but
at least in OCaml the functor language can be completely expanded at
compile time (or at least it was at the time of ocamldefun [1], unless
I'm mistaken).

Cheers.

[1] http://www.lri.fr/~signoles/ocamldefun/index.en.html

-- 
Stefano Zacchiroli -o- PhD in Computer Science \ PostDoc @ Univ. Paris 7
zack@{upsilon.cc,pps.jussieu.fr,debian.org} -<>- http://upsilon.cc/zack/
Dietro un grande uomo c'è ..|  .  |. Et ne m'en veux pas si je te tutoie
sempre uno zaino ...........| ..: |.... Je dis tu à tous ceux que j'aime


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?]
  2009-01-17 16:59     ` Jon Harrop
  2009-01-17 21:22       ` Kuba Ober
@ 2009-01-19 16:22       ` Yoann Padioleau
  2009-01-19 16:41         ` blue storm
  1 sibling, 1 reply; 22+ messages in thread
From: Yoann Padioleau @ 2009-01-19 16:22 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

Jon Harrop <jon@ffconsultancy.com> writes:

> On Saturday 17 January 2009 14:35:22 Kuba Ober wrote:
>
> In contrast, metaprogramming is the pedagogical example for algebraic 
> datatypes. There is almost no need for users to extend the abstract syntax 
> tree but there is huge value in being able to rewrite expressions using 
> pattern matching. 
> There is an idiomatic OOP solution to this problem that 
> involves visitor patterns and so forth but it is comparatively verbose, 
> obfuscated and unmaintainable.

Actually I think there are some good ideas in the visitor pattern. I
personnaly use a mix of pattern matching and of the visitor idiom in
one of my project about C program transformation
(http://www.emn.fr/x-info/coccinelle/).

The problem we had is that we manipulate the AST of C programs 
and some of our analysis need only to specify an action for 
specific cases, such as the function call case, and recurse
for the other cases. 
Here is an simplification of our AST: 

type ctype = 
 | Basetype of ...
 | Pointer of ctype
 | Array of expression option * ctype
 | ...
and expression = 
 | Ident of string
 | FunCall of expression * expression list
 | Postfix of ...
 | RecordAccess of ..
 | ...
and statement = 
 ...
and declaration =
 ...
and program = 
 ...

What we want is really give code like 

let my_analysis program = 
 analyze_all_expressions program (fun expr ->
   match expr with
   | FunCall (e, es) -> do_something()
   | _ -> <find_a_way_to_recurse_for_all_the_other_cases> 
 )

The problem is how to write analyze_all_expressions
and find_a_way_to_recurse_for_all_the_other_cases.

Our solution is to mix the ideas of visitor, pattern matching, 
and continuation. Here is how it looks like in our coccinelle project
using our hybrid-visitor API: 

let my_analysis program = 
 Visitor.visit_iter program {
   Visitor.kexpr = (fun k e -> 
    match e with
    | FunCall (e, es) -> do_something()
    | _ -> k e
   );
  }

You can of course also give action "hooks" for 
kstatement, ktype, or kdeclaration. But we don't overuse
visitors and so it would be stupid to provide
kfunction_call, kident, kpostfix hooks as one can just
use pattern matching with kexpr to achieve the same effect.


The code in Visitor.visit_iter is then of course a little bit tricky.
You can have a look in the source of coccinelle.

>
> -- 
> Dr Jon Harrop, Flying Frog Consultancy Ltd.
> http://www.ffconsultancy.com/?e
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?]
  2009-01-19 16:22       ` Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] Yoann Padioleau
@ 2009-01-19 16:41         ` blue storm
  2009-01-19 17:49           ` Richard Jones
                             ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: blue storm @ 2009-01-19 16:41 UTC (permalink / raw)
  To: Yoann Padioleau; +Cc: caml-list

On 1/19/09, Yoann Padioleau <padator@wanadoo.fr> wrote:
> What we want is really give code like
>
> let my_analysis program =
>  analyze_all_expressions program (fun expr ->
>    match expr with
>    | FunCall (e, es) -> do_something()
>    | _ -> <find_a_way_to_recurse_for_all_the_other_cases>
>  )
>
> The problem is how to write analyze_all_expressions
> and find_a_way_to_recurse_for_all_the_other_cases.

You should have a look at the Camlp4 "metaprogramming" facilities :
http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator

You would write something like :
let my_analysis program =
  let analysis = object (self)
    inherit fold as super
    method expr = function
    | FunCall (e, es) -> do_something (); self
    | other -> super#expr other
  end in analysis#expr

While sometimes a bit hairy, the object oriented layer makes it easy
to use a refine mapper or folders without writing all the heavy
plumbing yourself.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?]
  2009-01-19 16:41         ` blue storm
@ 2009-01-19 17:49           ` Richard Jones
  2009-01-19 17:52           ` Visitor in OCaml Christophe TROESTLER
  2009-01-21 20:09           ` Yoann Padioleau
  2 siblings, 0 replies; 22+ messages in thread
From: Richard Jones @ 2009-01-19 17:49 UTC (permalink / raw)
  To: caml-list

On Mon, Jan 19, 2009 at 05:41:35PM +0100, blue storm wrote:
> On 1/19/09, Yoann Padioleau <padator@wanadoo.fr> wrote:
> > What we want is really give code like
> >
> > let my_analysis program =
> >  analyze_all_expressions program (fun expr ->
> >    match expr with
> >    | FunCall (e, es) -> do_something()
> >    | _ -> <find_a_way_to_recurse_for_all_the_other_cases>
> >  )
> >
> > The problem is how to write analyze_all_expressions
> > and find_a_way_to_recurse_for_all_the_other_cases.
> 
> You should have a look at the Camlp4 "metaprogramming" facilities :
> http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator

Exactly what I was going to say.  For an example where this camlp4
facility is used, see ocaml-gettext.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Visitor in OCaml
  2009-01-19 16:41         ` blue storm
  2009-01-19 17:49           ` Richard Jones
@ 2009-01-19 17:52           ` Christophe TROESTLER
  2009-01-21 20:09           ` Yoann Padioleau
  2 siblings, 0 replies; 22+ messages in thread
From: Christophe TROESTLER @ 2009-01-19 17:52 UTC (permalink / raw)
  To: OCaml Mailing List

On Mon, 19 Jan 2009 17:41:35 +0100, blue storm wrote:
> 
> On 1/19/09, Yoann Padioleau <padator@wanadoo.fr> wrote:
> > What we want is really give code like
> >
> > let my_analysis program =
> >  analyze_all_expressions program (fun expr ->
> >    match expr with
> >    | FunCall (e, es) -> do_something()
> >    | _ -> <find_a_way_to_recurse_for_all_the_other_cases>
> >  )
> >
> > The problem is how to write analyze_all_expressions
> > and find_a_way_to_recurse_for_all_the_other_cases.
> 
> You should have a look at the Camlp4 "metaprogramming" facilities :
> http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator

You may also be interested in the paper "Code reuse through
polymorphic variants" by Jacques Garrigue:
http://www.math.nagoya-u.ac.jp/~garrigue/papers/fose2000.html

Regards,
ChriS


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Visitor in OCaml
  2009-01-19 16:41         ` blue storm
  2009-01-19 17:49           ` Richard Jones
  2009-01-19 17:52           ` Visitor in OCaml Christophe TROESTLER
@ 2009-01-21 20:09           ` Yoann Padioleau
  2009-01-22  4:03             ` [Caml-list] " Yaron Minsky
  2 siblings, 1 reply; 22+ messages in thread
From: Yoann Padioleau @ 2009-01-21 20:09 UTC (permalink / raw)
  To: blue storm; +Cc: Yoann Padioleau, caml-list

"blue storm" <bluestorm.dylc@gmail.com> writes:

> On 1/19/09, Yoann Padioleau <padator@wanadoo.fr> wrote:
>> What we want is really give code like
>>
>> let my_analysis program =
>>  analyze_all_expressions program (fun expr ->
>>    match expr with
>>    | FunCall (e, es) -> do_something()
>>    | _ -> <find_a_way_to_recurse_for_all_the_other_cases>
>>  )
>>
>> The problem is how to write analyze_all_expressions
>> and find_a_way_to_recurse_for_all_the_other_cases.
>
> You should have a look at the Camlp4 "metaprogramming" facilities :
> http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator

I've been there. I once implemented in camlp4 my own map-generator but
I now prefer not using fancy features or langage extensions. I prefer
to go back to basics. My solution does not use any fancy
stuff; just higher order functions, the continuation idiom,
and records. People reading your code, or downloading your
code then do not need to care about camlp4 (or objects).

Moreover, sometimes you need to do things slightly differently
from what is auto-generated and it becomes painful. For instance
it's possible to auto-generate the string_of_xxx for each
type xxx, but at some point you may want to do the printing
slightly differently, hide a few things, do some indentation
work (and use the Format library), etc, and at this point
you will have to write the tedious code. Camlp4
metaprogramming may save you some time at the beginning, but but do you really 
win that much time in the end ? 



>
> You would write something like :
> let my_analysis program =
>   let analysis = object (self)
>     inherit fold as super
>     method expr = function
>     | FunCall (e, es) -> do_something (); self
>     | other -> super#expr other
>   end in analysis#expr
>
> While sometimes a bit hairy, the object oriented layer makes it easy
> to use a refine mapper or folders without writing all the heavy
> plumbing yourself.

Thx, always interesting to see different ways to solve 
the same problem.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Caml-list] Re: Visitor in OCaml
  2009-01-21 20:09           ` Yoann Padioleau
@ 2009-01-22  4:03             ` Yaron Minsky
  0 siblings, 0 replies; 22+ messages in thread
From: Yaron Minsky @ 2009-01-22  4:03 UTC (permalink / raw)
  To: Yoann Padioleau; +Cc: Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 1069 bytes --]

On Wed, Jan 21, 2009 at 3:09 PM, Yoann Padioleau <padator@wanadoo.fr> wrote:

>
> Moreover, sometimes you need to do things slightly differently
> from what is auto-generated and it becomes painful. For instance
> it's possible to auto-generate the string_of_xxx for each
> type xxx, but at some point you may want to do the printing
> slightly differently, hide a few things, do some indentation
> work (and use the Format library), etc, and at this point
> you will have to write the tedious code. Camlp4
> metaprogramming may save you some time at the beginning, but but do you
> really
> win that much time in the end ?
>

Yes!

Sexplib is entirely an exercise in camlp4 metaprogramming, and it has saved
us countless hours of work and simplified our lives greatly.  Yes, if you
need lots of variations on your serialization and deserialization functions
then camlp4 is a painful way of going about it.  But things like sexplib act
as general language extensions which can provide broadly useful
functionality at a low cost.  I really think it's a very big win.

y

[-- Attachment #2: Type: text/html, Size: 1408 bytes --]

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2009-01-22  4:03 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-16 15:18 C++/C# inheritance is bad? Kuba Ober
2009-01-16 15:58 ` [Caml-list] " Richard Jones
2009-01-16 16:28   ` On the benefits of OO, Was: " Jan Kybic
2009-01-17 12:40     ` Oliver Bandel
2009-01-16 18:27 ` Raoul Duke
2009-01-16 21:42   ` Kuba Ober
2009-01-17  3:14     ` Sashan Govender
2009-01-17 14:07       ` Kuba Ober
2009-01-18  6:24         ` Stefano Zacchiroli
2009-01-17 13:27 ` Jon Harrop
2009-01-17 14:35   ` Kuba Ober
2009-01-17 16:59     ` Jon Harrop
2009-01-17 21:22       ` Kuba Ober
2009-01-17 22:17         ` Jon Harrop
2009-01-17 23:29           ` David Teller
2009-01-17 23:49             ` Jon Harrop
2009-01-19 16:22       ` Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] Yoann Padioleau
2009-01-19 16:41         ` blue storm
2009-01-19 17:49           ` Richard Jones
2009-01-19 17:52           ` Visitor in OCaml Christophe TROESTLER
2009-01-21 20:09           ` Yoann Padioleau
2009-01-22  4:03             ` [Caml-list] " Yaron Minsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).