About 3 years ago I got interested in ML (machine learning) and quickly realized the “lingua franca” of ML was Python and the numerous tools used to massage data, apply it to ML algorithms, and create visualizations (Pandas, Numpy, Scikit-Learn, Scipy, Plotly, Matplotlib, etc.)
One of the best features of Python is its brevity in expressing algorithms. The syntax is sparse and, with list comprehensions, lamdbas, and first-class functions, it’s possible to explore a problem without a lot of preliminary definitions and syntactical cruft. It’s really quite nice, but I wished often I could do similar things in C#
With the latest additions to C# 7.x, that time has arrived to a great extent.
To give some idea of what’s possible now, let’s compare a function written in Python with the same function in C# – using the latest features. I think you’ll find writing less C# is getting easier to do.
The function is permutations. Here is one way to do it in Python:
def perms(a):
def permsHelper(a,start,end,perms):
if start == end:
perms.append(a.copy())
return
for i in range(start,end):
a[i], a[start] = a[start],a[i]
permsHelper(a,start+1,end,perms)
a[i], a[start] = a[start],a[i]
perms = []
permsHelper(a,0,len(a),perms)
return perms
a = [1,2,3]
print(perms(a))
Some key features of Python being used in the above implementation are: nested functions, tuples, and tuple destructuring/assignment.
C# has added these features to the language, so it is possible now to achieve nearly the exact same implementation in C# syntax:
List<string> Perms(string word) {
var perms = new List<string>();
void PermsHelp(char[] a,int start, int end) {
if (start == end) {
perms.Add(new string(a));
return;
}
for (int i=start; i<end; i++) {
(a[i], a[start]) = (a[start], a[i]);
PermsHelp(a, start + 1, end);
(a[i], a[start]) = (a[start], a[i]);
}
}
PermsHelp(word.ToArray(),0,word.Length);
return perms;
}
Yes! C# now allows nested functions and, with the new ValueTuple and supporting “()” syntax, along with destructuring/assignment support, at least in this example, there is practically a 1-to-1 equivalence between the lines of code of the two implementations.
There’s lots more to explore: local ref variables, out variables, and expression-bodied members, which all contribute to much cleaner code. For details, checkout the Microsoft docs here.
Now, if only we had a good C# alternative to Jupyter notebooks. I’ve been thinking of taking a stab at it 🙂