jducoeur: (Default)
[personal profile] jducoeur
This one is a pure C# language rant, which I believe applies almost word-for-word to Java as well, but I'm less up on the current state of that language.

I am noticing today, far from the first time, that I spend a ridiculous amount of time typing constructors. Here's the skeleton that I just typed (I don't think it gives away any company secrets to say that I'm writing a nice beefy resource-management system right now):
   internal class ResourceRequest
   {
      public ResourceRequest(string name, string resourceType, IDictionary other)
      {
         m_Name = name;
         m_ResourceType = resourceType;
         m_Other = other;
      }

      public string Name { get { return m_Name; } }
      public string ResourceType { get { return m_ResourceType; } }
      public IDictionary Other { get { return m_Other; } }

      private string m_Name;
      private string m_ResourceType;
      private IDictionary m_Other;
   }

That's terribly, terribly ordinary object-oriented code. Damned near every class has the same pattern: a constructor whose parameters simply get assigned to private members, and those members get exposed as properties. It's good programming practice -- very flexible, easy to modify the behaviour down the road, etc. But damn -- it's a lot of pointless verbiage, and boilerplate always gets under my skin.

So I'll add this to my Perfect Language Wishlist: it would be lovely to be able to condense all of this using some attributes and a little new syntax. I can easily see boiling the above down into:
   internal class ResourceRequest
   {
      public ResourceRequest(Name, ResourceType, Other)
      {
      }

      [ReadProperty("Name")]
      private string m_Name;
      [ReadProperty("ResourceType")]
      private string m_ResourceType;
      [ReadProperty("Other")]
      private IDictionary m_Other;
   }

This represents two specific enhancements. First, you can just declaratively say "expose this member as a read-only property" (there would obviously be a version for read/write as well), thus preserving the separation of the member and property in case we want to introduce indirections later, but stating the simple common case concisely. Second, you can simply give the name of a property as an untyped constructor parameter, meaning "assign this parameter directly to this property".

I'm not sure the above syntax is ideal -- it might want a little additional syntactic sugar to make it clearer -- but the basic concept is straightforward. If the language demands a very common piece of boilerplate, you should simplify the language to reduce that boilerplate.

Along these lines: it would be a Very Nice Thing to be able to specify optional properties as part of a constructor call. C# is curiously inconsistent in this regard. Attributes actually have exactly the behaviour I want, with things like:
[XmlElement(ElementName="foo")]
string m_Foo;

The above means "attach an XmlElementAttribute to m_Foo, and assign the value 'foo' to the ElementName property". This is a clean, elegant way to get a lot of flexibility in construction, and used properly would allow you to staunch the explosion of constructor signatures common in complex objects. But for some reason, they only allow it in Attributes -- you can't use the same syntax for ordinary C# objects, so you have to replace it with multiple lines of assignment, resulting in code that is both longer and muddier.

So the other immediate wishlist item is to steal this syntax from attributes, and allow any constructor invocation to do this. It would reduce code size immediately, and generally improve readability and maintainability by clarifying that these particular property assignments are intended as part of the initial state of the object...

(no subject)

Date: 2005-02-09 07:17 pm (UTC)
From: [identity profile] metahacker.livejournal.com
I agree, in the main. Just yesterday I was creating classes with *monster* constructors (>12 parameters), the body of which consisted of setFoo(foo); setBar(bar); etc.

I'd vastly prefer:
protected readwrite String name;
private readonly Integer uniqueID;
public constructor ClassName(name, uniqueID);
public constructor ClassName(name) {
  // assignments happen before this
  uniqueID = generateID;
}
to mean, or maybe precompile to,
private String name;
protected Integer uniqueID;

public ClassName(String name, Integer uniqueID) {
  setName(name);
  setUniqueID(uniqueID);
}

public ClassName(String name) {
  setName(name);
  // assignments happen before this
  uniqueID = generateID;
}

public String getName() { return name; }
public void setName(String name) { this.name = name; }

public Integer getUniqueID() { return uniqueID; }


I mean, that's a 60% savings in characters, and about 12 different possibilities for errors removed, with a horribly trivial example.

(no subject)

Date: 2005-02-09 09:09 pm (UTC)
From: [identity profile] querldox.livejournal.com
Bring back Lisp!

(optional parameters already and easily usable in the language, easy to write macros to simplify boilerplate, etc.)

(no subject)

Date: 2005-02-10 12:02 am (UTC)
From: [identity profile] asim.livejournal.com
Bring back Lisp!
*nods*
Scheme was one of the 2 languages we learned in CS in college. In fact, I just downloaded a scheme interpreter a couple of weeks ago, and whip it out from time to time to work in a different framework. I do miss it...

(no subject)

Date: 2005-02-09 11:58 pm (UTC)
From: [identity profile] asim.livejournal.com
Yep. I had a similar issue with building constructors in Perl, which I solved by means of templating. And now, there are modules in Perl for building accessors, and, from what I recall, Perl 6 is working on a solution for both problems. But Perl 6 is working on _everything_...slowly. (And I'm a fan of the language, from what I've read of it).

The main issue with your solution, from a language standpoint, is that it can end up, easily, as a language-within-a-language. And a lot of languages try to avoid that situation, for a variety of reasons. You'd want your "syntactic sugar" to read much like the rest of the code, and not be a major departure in it's structure.

Hmmm. Now that I think about it, I seem to recall reading somewhere that C# does have some of the capabilities you mentioned. Since I don't work with it everyday, I'm not sure, but I'd bet someone else on here knows what I'm talking about -- if it exists.

Profile

jducoeur: (Default)
jducoeur

October 2025

S M T W T F S
   12 34
567891011
12131415161718
19202122232425
262728293031 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags