Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

Syndication

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Question of the Day -- What's Worse?

From Twitter yesterday, I was griping about how once you use a Generics Constraint once and suddenly that same constraint has to immediately ripple through the call stack.  Scott Allen posed me a stumper of a question:

What's worse: generic constraints, or checked exceptions [in java]?

Oh wow, that's a nasty choice.  Can I have neither?  I'd call both things Noise Code.  Smelly, useless, noise code.

  • Generics Constraints:  90% of the time it's just to make the compiler shut up and let my code work.  Dear C# team, could you deemphasize all the COM interop work in C# and making C# do kloogey dynamic typing, and GIVE ME FAR BETTER TYPE INFERENCE ON GENERICS SO I CAN GET SOMETHING DONE (contra/covariance makes your little academic hearts go pitter patter, but that won't really help me much)!!!!!    Anyway, ReSharper can mostly figure out how to propogate the generic constraints, but it gets confused easily and sometimes the constraints will conflict and...  Human intervention is usually necessary.  Andy Sherwood calls this  "the where tentacles."  Nice.
  • Checked Exceptions.  Much more pervasive, but IntelliJ can handle adding the "throws blah" stuff without any trouble.  The problem is that checked exceptions are so much more common and pervasive.  Needless to say, I don't find checked exceptions to be the slightest bit useful.
I guess I'd rather live with the generics constraints than waste time with checked exceptions.  Now, keep checked exceptions out of the language, give me F#/OCaml style type inference instead of a nanny compiler (are you sure it's okay for this object to do this?  Confirm or deny), and make ALL methods and properties virtual by default, and I'm  a happy camper.  If I want dynamic typing, I'll use IronRuby.  If I need office integration, I'll get a contracter to write VB.Net.

 


Posted Wed, Dec 3 2008 7:49 AM by Jeremy D. Miller

[Advertisement]

Comments

Dew Drop - December 3, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - December 3, 2008 | Alvin Ashcraft's Morning Dew
on Wed, Dec 3 2008 9:37 AM

Pingback from  Dew Drop - December 3, 2008 | Alvin Ashcraft's Morning Dew

Mike Strobel wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:03 AM

I generally agree with you about typed exceptions, but I'm not sure how much more the C# team can do for generics aside from providing better support for variance.  C#'s strict type safety is one of its virtues and helps lead developers into the "pit of success", as Brad Abrams likes to say.  Generic constraints offer a bit more control, though they are more limited in C# than in some other languages (e.g. you cannot constrain to an Enum in C#, but you can in C++/CLI).  It seems to me that if you're looking for more flexibility, you should be actively trying to *avoid* constraints on your generic parameters.  That said, I'm curious to hear what changes you think should be made.  I'm hardly an authority on the subject, so perhaps you have some insights that I hadn't considered.

As for making all methods and properties virtual by default, I urge you to consider the performance ramifications.  All method and property accessor invocations would result in a vtable lookup by default.  While this may seem like an insignificant performance hit (and for individual method calls, you might be right), but it really adds up.  There's no doubt in my mind that the C# team made the right call here.

Jeremy D. Miller wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:24 AM

@Mike Strobel,

Thanks for the comment.

In regards to Generics, it's stuff like:

public void Do<T>() where T : new() -- forget this.  I don't want to have to define that constraint

THIS CODE:

           ForController<HomeController>("home")

               .Map(c => c.Index()).ToView<Index>()

               .Map<DashboardRequestViewModel, DashboardResponseViewModel>((c, input) => c.Dashboard(input)).ToView<Dashboard>()

               .Map(c => c.UserWorkflowData()).ToJson()

               .Map<GridTaggedItemsRequestModel, GridItemsViewModel>((c, i) => c.MyTaggedItems(i)).ToJson()

The call to Map<T, U>(Func<T, U> func), I want type inference here by default the way it can with a simple arguments.

"As for making all methods and properties virtual by default, I urge you to consider the performance ramifications."

I'm aware of the arguments for the sealed by default argument, and I've never bought into the performance argument.   There's far more very large systems built with Java where it's virtual by default, and they're doing fine.  I think the tax on productivity and code noise is more important than a very minor performance optimization

Frank Quednau wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:27 AM

If some public method in a public class of yours has a generic constraint, and in there you instantiate some class with that type argument, how could you avoid by design of a statically typed language that you don't need the same or a stronger constraint on said class?

From my experience a design decision may have to be re-thought if the constraints are rippling through the system far too wide. If the constraints just "fall into place" it is rather satisfying. Admittedly, changing constraint decisions is quite painful.

Mike Strobel wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:44 AM

@Jeremy: I agree completely that better type inference would be a welcome improvement.  Further, that type of improvement is preferable because it mostly affects  the compiler and does not significantly alter the language specification.

Aside from the performance issue regarding methods being virtual by default, there is the issue of versioning.  In a perfect world, developers would never forget to seal methods that should not be overridden and would not expose methods as virtual if altering the behavior could break the functionality of the class.  Unfortunately, that is a long shot from reality.  We can certainly agree to disagree, but I believe that having methods sealed by default results in more maintainable code, particularly when that code is written by junior developers.

Jan Van Ryswyck wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:48 AM

The cruft that generic constraints bring to the table is something that bothers me almost every day but couldn't get so nicely expressed in a blog post like yours. Soooo true.

James Curran wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 10:53 AM

Unless you want your users experiencing bizarre errors are JIT time (or give up the ability to have generic class definitions in separate assemblies), there is really no way around generic constraints.

Jeremy D. Miller wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 11:00 AM

@James,

"there is really no way around generic constraints"

I don't agree.  I think you could accomplish some of the same goals as generic constraints with more type inference.  The compiler can still enforce "implicit" constraints at compile time.  For runtime errors, I go for the age old dynamic typing argument:  test your code.

Stephen wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 4:10 PM

Cannot say that generic constraints have ever offended me to be honest.. so to me this is a bit confusing.

Jeremy D. Miller wrote re: Question of the Day -- What's Worse?
on Wed, Dec 3 2008 5:47 PM

Ok, I was terribly wrong about co/contra variance.  I want it now,  I propose a .Net 3.5 SP2 release just to do that.  I'm getting extremely pissed at the number of overloads I'm having write.

Lucian Wischik wrote re: Question of the Day -- What's Worse?
on Thu, Dec 4 2008 1:03 AM

Could you give a complete sample of the sort of thing you want where type inference doesn't work today? I tried this code, which I thought at first was similar to what you want, and it inferred fine, so I must be missing something.

public static class Program

{

   static void Main(string[] args)

   {

       var x = new System.Collections.Generic.List<int>();

       var y = x.Map((i) => i.ToString()).Map((s) => System.Int32.Parse(s));

   }

   static System.Collections.Generic.IEnumerable<U> Map<T,U>(this System.Collections.Generic.IEnumerable<T> x, System.Func<T,U> f)

   {

       return new System.Collections.Generic.List<U>();

   }

}

Kent Boogaart wrote re: Question of the Day -- What's Worse?
on Thu, Dec 4 2008 8:27 AM

Also annoying are the, um, constraints on constraints. Why can't I constrain to a type with a particular ctor signature? And don't get me started on operators...

Lucian Wischik wrote re: Question of the Day -- What's Worse?
on Thu, Dec 4 2008 11:25 AM

Instead of "constraints on new", I think a much nicer pattern is to pass a delegate whose job it is to construct the thing. Here's some code which requires a constructor of signature (int,string):

   Sub f(Of T)(ByVal f As Func(Of Integer, String, T))

       Dim newlyConstructedObject = f(1, "hello")

   End Sub

   Sub Main()

       f(Function(i, s) String.Format("{0}:{1}", i, s))

   End Sub

This way is more flexible because accessibility of the delegate is as it was at the callsite of the generic function where it's supposed to be. Also it supports the object-initializer idiom.

David Nelson wrote re: Question of the Day -- What's Worse?
on Mon, Dec 22 2008 3:30 PM

I absolutely agree with Lucian. Constraining to a particular constructor signature, even if it is the default signature, is a perversion of OOP and the concept of constructors.

As for virtual-by-default, nothing would more quickly destroy the extensibility of frameworks (not just the BCL), and I am very glad that the .NET designers made the right decision here. If they hadn't I probably wouldn't even be using .NET today.

K. Scott Allen wrote Thoughts on the Code Contracts Preview for .NET 4.0
on Tue, Feb 24 2009 12:54 AM

A new Code Contracts preview is now available on DevLabs. Code Contracts will be part of the base class...

BusinessRx Reading List wrote Thoughts on the Code Contracts Preview for .NET 4.0
on Tue, Feb 24 2009 1:11 AM

A new Code Contracts preview is now available on DevLabs . Code Contracts will be part of the base class

Add a Comment

(required)  
(optional)
(required)  
Remember Me?