Phil Trelford's Array
POKE 36879, 255

C# Light Syntax

June 21, 2011 14:53 by phil

Java and C# have somewhat reduced the ceremony over C++ by not requiring header files, but they are still both quite verbose. What would it look like if C# went one step further and adopted a light syntax like Python, where white space is significant?

Let’s start with an immutable Person class implemented in idiomatic C#:

namespace MyCompany.MyProduct
{
    public class Person
    {
        public Person(string name, int age)
        {
            _name = name;
            _age = age;
        }

        private readonly string _name;
        private readonly int _age;

        /// <summary>
        /// Full name
        /// </summary>
        public string Name
        {
            get { return _name; }
        }

        /// <summary>
        /// Age in years
        /// </summary>
        public int Age
        {
            get { return _age; }
        }
    }
}

Now lets extract the namespace, public modifiers, return statements and curly braces:

class Person

    Person(string name, int age)    
        _name = name;
        _age = age;    

    private readonly string _name;
    private readonly int _age;

    /// <summary>
    /// Full name
    /// </summary>
    string Name 
        get _name;    

    /// <summary>
    /// Age in years
    /// </summary>
    int Age 
        get _age;

Not too bad 30+ lines reduced to 20! But we could do more, what if triple slash comments were assumed to be summary text by default:

class Person

    Person(string name, int age)    
        _name = name;
        _age = age;    

    private readonly string _name;
    private readonly int _age;

    /// Full name
    string Name 
        get _name;    

    /// Age in years   
    int Age 
        get _age;

16 lines and dare I say it, no less readable!

Perhaps we could merge the class declaration and constructor to define a closure over the class members?

class Person(string name, int age)           

    /// Full name
    string Name 
        get name;    

    /// Age in years   
    int Age 
        get age;

9 lines and some might say the intent is actually clearer now!

Which incidentally isn’t a million miles away from what we can do with an F# class today:

type Person(name:string,age:int) =

    /// Full name
    member person.Name = name

    /// Age in years
    member person.Age = age
 

Or we could go one step further and take it down to just 1 line with an F# record:

type Person = { Name:string; Age:int }

It’s probably worth mentioning that both the F# class and record types can be consumed as classes from C# in exactly the same way as the original C# example.

So, if like me you’re a little bored of reading and writing verbose C# class declarations then F# might just be your thing!


Tags:
Categories: C# | F# | .Net
Actions: E-mail | Permalink | Comments (18) | Comment RSSRSS comment feed

Comments

June 21. 2011 15:20

Joe

I agree the the 3 slashes meaning summary text, but don't forget C does support this context:

class Person
{
Person(string name, int age)
{
   Name=name;
   Age =age;
}

public string Name{get; private set;}

public int Age{get; private set;}
}

which isn't that bad. Now it would be nice if you could default access to public instead of private

Joe

June 21. 2011 15:22

Joe

i mean c#, not c :)

Joe

June 21. 2011 15:30

Federico Lois

Hardly a good example:

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person ( string name, int age )
    {
       this.Name = name;
       this.Age = age;
    }
}

I like what F# brings to the table to the .Net development as it is a very natural syntax to define concurrent constructions. However, the use of barebones C# 1.0 is not fair for comparison purposes.

@federicolois

Federico Lois

June 21. 2011 17:11

Leo

Significant whitespace is the tool of the devil.

Leo

June 21. 2011 17:37

Mauricio Scheffer

There's already something very similar to a white-space sensitive C#: Nemerle: http://nemerle.org/Indentation-based_syntax

For a more pythonic feel while keeping static typing, there's Boo ( http://boo.codehaus.org/ ) and Cobra ( http://cobra-language.com/ )

Mauricio Scheffer

June 21. 2011 17:49

Jonathan Allen

> Now lets extract the namespace, public modifiers, return statements and curly braces:

I would prefer you do it the other way and remove the redundant private modifiers. Marking something as public should be a concious choice, not the default.

As for the rest, I find it interesting. I don't know if I want whitespace for block delimination, but it is worth talking about.

Jonathan Allen

June 21. 2011 22:11

Phil

Joe, federicolois,

C# 3.0's auto-implemented properties are certainly more concise, and private set stops derived classes from setting the property. However they do not explicitly convey that the class is immutable after construction.

MSDN on Auto-Implemented Properties: msdn.microsoft.com/en-us/library/bb384054.aspx
Luca Bolognese on creating immutable value objects in C#: blogs.msdn.com/.../...-c-part-i-using-a-class.aspx
Eric Lippert on Immutability in C#: blogs.msdn.com/.../...e-kinds-of-immutability.aspx

Cheers,
Phil

Phil

June 21. 2011 22:33

Phil

Leo,

Personally I find moustaches all over the place a little disturbing :{)

www.cracked.com/.../

Phil

Phil

June 22. 2011 03:10

Roger Lipscombe

You're assuming that conciseness is the be-all and end-all of language design.

Roger Lipscombe

June 22. 2011 06:58

TechNeilogy

Awesome.  F# and Python have made me a convert to significant whitespace.  In the C# example, I'd find a way to get rid of the trailing semicolons as well.

TechNeilogy

June 22. 2011 14:02

dude

Not sure what's wrong with C# already in this regard:

var person = new { name = "joe", age = 22 };

Those properties are readonly and it's no more complex than one-liner as in your F# example.

dude

June 22. 2011 23:29

Phil

Dude,

"Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first." - From MSDN on "Anonymous types in C#": http://msdn.microsoft.com/en-us/library/bb397696.aspx

That said, you can't define methods, events, etc. on them. You also can't access the type information outside of the method they are defined in without resorting to reflection (although the dynamic keyword can help here).

The F# Record type is not anonymous, it produces the same type as the original C# code, including automatically generating a constructor for you, and it can be extended with methods and events.

There is a great introduction to F# Records on Wikibooks:
en.wikibooks.org/.../Tuples_and_Records

Thanks,
Phil

P.S. Enjoyed the irony of an anonymous post on anonymous types.

Phil

June 23. 2011 18:53

reno

This is an awesome example and is motivating to continue trying to learn F# despite how hard it is to wrap my head around it atm.

reno

June 24. 2011 08:06

Jon Harrop

@Roger Lipscombe: Making an observation about brevity is obviously not "assuming that conciseness is the be-all and end-all of language design".

Jon Harrop

June 24. 2011 15:19

Mike

In Scala all of this can be done in one line:
class Person(var name:String,var age:Int);

Mike

October 21. 2011 19:42

Associator

@Federico Lois and @Joe

F# 3.0 has auto-properties with initial values something even C# doesn't support, so a mutable class with get and set properties is even more concise than in C#.

See here: msdn.microsoft.com/.../dd483467(v=VS.110).aspx

/// mutable class with auto-properties
type Person(name : string, age : int) =
    /// Full name
    member val Name = name with get, set
    /// Age in years
    member val Age = age with get, set


F# is not a 1-trick pony, it's a true general purpose multi-paradigm language.

Associator

August 30. 2012 00:25

trackback

Blog 101

Blog 101

Phil Trelford's Array

October 13. 2013 07:11

trackback

DDD North 2013

DDD North 2013

Phil Trelford's Array

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading