Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

C# and multimethods

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Lee Crabtree - 18 Mar 2008 21:26 GMT
I'm almost positive that this isn't possible in C#, unless there's something
REALLY esoteric I haven't come across, but I was curious why something akin
to multimethods in Lisp isn't possible in C#.  Specializing function arguments
by type is useful, but sometimes it would be really nice to be able to write
functions specialized on the values of arguments.  By way of example, instead
of something like this:

public class Thing
{
    public void DoSomething(int var)
    {
        switch(var)
        {
            case 0:
                //do work for the value of 0
                break;
            case 1:
                //do work for the value of 1
                break;
            default:
                break;
        }
    }
}

That's an extremely simple and contrived example, but the point still holds.
If I've got a lot of those kinds of cases, this kind of function gets unwieldy
fast.  Yes, I could write separate functions for the work to be done for
each value, but I'd still need some kind of steering function to pick the
right one.  Every time I need to add support for a new value, I've got to
modify this function.  In Lisp, I would probably do something akin to this:

(defmethod DoSomething ((var (eql 0)))
    ;do work for value 0
    )

(defmethod DoSomething ((var (eql 1)))
    ;do work for value 1
    )

(defmethod DoSomething ((var integer))
    ;just return
    )

If I ever need to add support for a new value, I don't have to change any
existing code, I just have to write a new function specialized on the value
I want.  That obviously could get really hairy for complex types, and there's
probably a whole host of reasons why this doesn't work in C#, but since I
don't know, I thought I'd ask.

Lee Crabtree
Marc Gravell - 18 Mar 2008 21:33 GMT
I think the answer is "no", but I believe F# supports this. That's
fairly close to the limit of my F# knowledge, however ;-p

Marc
Peter Duniho - 18 Mar 2008 22:54 GMT
On Tue, 18 Mar 2008 13:26:20 -0700, Lee <Crabtree> wrote:

> I'm almost positive that this isn't possible in C#, unless there's  
> something REALLY esoteric I haven't come across, but I was curious why  
[quoted text clipped - 4 lines]
> to be done for each value, but I'd still need some kind of steering  
> function to pick the right one.

I don't see how adding a new case to a switch statement is significantly  
more effort than explicitly stating the matching value as a parameter to  
the method.  In either case, we're only talking about typing less than a  
dozen extra characters.  What is it about the Lisp syntax that you find  
significantly superior?  Is it just the typing, or is there something else?

It's been decades since I use Lisp or its derivatives, but my recollection  
is that these languages have a fundamental underlying design choice that  
the interpreter is matching _everything_ to figure out what gets called.  
As a functional language, it makes sense in the language for values in the  
parameter list to affect which method gets called, because it's not just a  
parameter list so much as just some expression that's part of what's  
matching the function to be called.

While it's been way too long ago for me to recall the specifics in a  
useful way, what I do recall is that there's a genuine fundamental  
difference in the way these languages act that would implicitly prohibit  
C# supporting the same thing.  As a procedural language, C# requires  
everything to be written in an imperative way, which precludes the sort of  
overloading you're asking for.

That said, while C# doesn't allow method overloads based on the value of a  
parameter, you could easily implement a dispatch array or dictionary of  
delegates that would reduce the typing to even fewer characters than the  
small number required by a switch statement.

I admit it's not ever going to be quite as elegant as the syntax used by  
Lisp, but given that the basic design underlying this desire is IMHO a bit  
awkward in the first place, I'm not personally all that concerned that a  
little extra typing might be required to do it.  If you really don't like  
the switch, there are other ways to do it.

Pete
Lee Crabtree - 19 Mar 2008 15:31 GMT
> On Tue, 18 Mar 2008 13:26:20 -0700, Lee <Crabtree> wrote:
>
[quoted text clipped - 43 lines]
>
> Pete

You're right that it's not any kind of savings in typing.  The main reason
I like the multimethod syntax is that I don't ever have to touch code that's
already working.  Call me paranoid, but I hate modifying code that's been
working without a problem, even to do something that doesn't alter the previous
functionality.  The other reason would be that I'm a little anal about one
function doing one thing whenever possible, so I'd rather write a new function
that performs a certain way for a certain value.  Of course, there are plenty
of ways to do it without using multimethods, but the syntax has always seemed
a lot cleaner and readable to me.

Like I said, I'm not surprised that C# doesn't support it, and I'm certainly
not complaining.  I was more interested in the why.

Lee
Peter Duniho - 19 Mar 2008 19:15 GMT
On Wed, 19 Mar 2008 07:31:56 -0700, Lee <Crabtree> wrote:

> You're right that it's not any kind of savings in typing.  The main  
> reason I like the multimethod syntax is that I don't ever have to touch  
> code that's already working.

Okay, well I understand that.  That said, you seem to be pretty specific  
about your definition of "code that's already working".  After all, adding  
a method to a module file is, in some sense, "touching" the code even if  
you're not adding the next text inside the logical boundary of another  
method.

Also, I'm not sure a simple method that contains only a switch meant for  
dispatching method calls is something that is at a high risk for breaking  
changes, especially in a way that would disable previously-working code (I  
could see messing up the new case statement, but previously added ones  
would take a lot more work to break).

All that said, as I mentioned you could use an array or dictionary to hold  
parameter values and delegates to call for those values and automate the  
whole thing without a switch.  Adding a new method would involve just  
adding a line to initialize a new element of the collection and IMHO that  
would be no more likely to break other code than would adding a new method  
to the file.

Pete

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.