As I write more and more code, the more I want simplicity and ease of understanding over typing a few less characters or having more elegant code.
I had a 24 year old developer report to me that apparently thought his bonuses were tied to how many operations he did on a single line of code.
He consistently wrote unbelievably complex lambda expressions with multiple conditional operators that would make a single line take up at least 1.5 screenfulls in Visual Studio on a 1920x1080 resolution monitor. These lines were impossible to debug and had to be inevitably broken up.
For a while I thought he was following the conventions laid forth in:
https://www.thc.org/root/phun/unmaintain.html
...but he really seemed to be genuinely thinking he was accomplishing something good by doing this.
I'm with you though. I'll take simplicity.
I worked for many years on a FoxPro application with a 10-character limit. The first version of the program was written under a two character limit. This never bothered my boss, who was a terrible typist and always used short names anyway. But I at some point took up the practice of descriptive names, on top of the Hungarian notation we'd adopted for sanity. So I was exceeding the limit all over the place.
Ten years later, guess who had to convert the program to VFP, which has no variable name limit. And no compile-time checks on variables, even when they are declared. Glad that year's over.
http://blogs.msdn.com/b/lukeh/archive/2007/10/01/taking-linq...
There's some of this in all languages, of course, but "this bit of sugar will make the code cleaner and easier to read" assumes that everyone will adopt a new set of idioms wholesale (which they usually don't).
Scheme, via SICP, is much easier to get started with, and one can learn the basics with that quickly (including getting much more comfortable with the sequence abstractions -called LINQ in .NET- than even the average .NET developer).
All these reasons are also why I greatly prefer F#. If you stay away from much of the OO system, F# is much simpler to teach in my experience. At my company right now another team is putting together an F# training program intended to teach our QA automation.
Comparatively the string trick, read-only properties and lambda syntax for simple methods seem very easy to digest.
True, coming from Java where you have to type a lot to get a simple thing done I seem to be gravitating towards languages which have clean, simple syntax that allows you to actually think about the problem. I've been playing with python and scheme, I'll have a go with C# soon, now its been open-sourced.
Syntactic sugar can be that, but not THIS syntactic sugar they propose here.
Here it makes the code easier to read and the intent more clear.
Reading code should be like reading a nice book.
macromaniac: "Patience, I'm still working on salad..."
Why this:
public int X { get; }
public int Y { get; } = 5;
And not this: public int X get;
public int Y get = 5;
The braces serve absolutely no purpose anymore, the semi-colon doesn't serve as a separator between statements. So why leave them?If you care about clean code, here's an even better way public readonly int X; They are not exactly the same but they are equivalent in most cases. In exotic cases where you're required to use auto-getters, adding the brackets wouldn't hurt.
As mentioned in my other reply. If that were the case, why have they just changed the method declaration syntax? It's inconsistent and therefore unacceptable right? If everything has to be consistent we wouldn't have LINQ, lambdas, generics, etc.
The braces are for scope in C# and all C derivative languages. There is no scope being created here and no requirement for scope. Also there are other places in C# where the scoping braces can be dropped [when there's only a single statement within]:
if(foo == 1)
{
bar();
}
Can be written: if(foo == 1)
bar();
So I don't see the inconsistency at all if they were to drop the braces.> If you care about clean code, here's an even better way public readonly int X
That's what I use. Cue the next round of discussion about fields and properties...
They did change the property declaration syntax too.
public int X => 5;
is the same as public int X { get { return 5; } }
This is exactly the same change they made to the method declaration syntax, so I'm not sure what you're complaining about.Of course it isn't identical to public int X { get; } because the latter is assignable in the constructor. But comparing _that_ to methods is apples to oranges since methods aren't assignable.
It just seems so pointless and ugly, no one is going to write them like this (well, seems unlikely anyway):
public int X
{
get;
} = 5;
So they're no longer providing a scope/block structure. How would it break backward compatibility? I'm not suggesting they remove the scoping for properties, it's clearly needed for {get;set;}, but as far as I can tell I can't think of any existing property-name suffix keyword in the C# grammar, so it seems it wouldn't be too hard to get it to work.The only reason I can think of to not do it is to reserve the option of post property-name keywords for future features.
I've been using public readonly fields instead for a number of years now because of the constant boilerplate. I doubt I'll change to use these auto-properties for the same reasons.
public int Y => 5;If the value is always going to be 5, then use a const.
I know its hard http://blog.coverity.com/2013/11/20/c-non-nullable-reference...
But dang I would appreciate it. So much code is cluttered with null checks that increases the robustness of the code at the cost of correctness, readability, and poorly defined behavior.
For example, let's say I am calling a function which returns an object:
var myStuff = new GiveMeStuff().GenerateStuff(1337);
The return of this value can be valid "stuff," an exception, or null. If we remove null as an option, what happens when internally an exception is thrown within GenerateStuff()? Does it re-throw that exception? Or do we now need a property within stuff like (bool)myStuff.validStuff?Null is a very useful way of communicating something failed. It is useful firstly because it is a "cheap" comparison and secondly because it saves us from having to place try{}catch(){} blocks around all of the things.
So my question is: without null how are we communicating failure? More exceptions? Or more clutter within our objects.
http://www.infoq.com/presentations/Null-References-The-Billi...
I wonder if there is any chance of Rust getting an abbreviation like `?` so you can write `int?` instead of `Option<int>`. I'm just starting to explore the language, but it seems like a lovely addition.
I wouldn't expect Rust to go back to shorthand after leaving it.
public override string ToString() { return String.Format("({0}, {1})", X, Y); }
public override string ToString() => "(\{X}, \{Y})"
Could it go even further? This isn't paper after all, on screen why shouldn't it look like; public override string ToString() => "(X, Y)"
where the X and Y are either slight italics or underlined or colored to indicate they mean X and Y the variable not X and Y the letters. The IDE would let you just toggle the state between 'variable' and 'literal' with the keyboard.We also get better array initializers:
public JObject ToJson() {
var r = new JObject();
r["x"] = X;
r["y"] = Y;
return r;
}
becomes: public JObject ToJson() => return new JObject() { ["x"] = X, ["y"] = Y };
That's cool! Next comes the null-conditional operators: public static Point FromJson(JObject json)
{
if (json != null &&
json["x"] != null &&
json["x"].Type == JTokenType.Integer &&
json["y"] != null &&
json["y"].Type == JTokenType.Integer)
{
return new Point((int)json["x"], (int)json["y"]);
}
return null;
}
Becomes... public static Point FromJson(JObject json)
{
if (json?["x"]?.Type == JTokenType.Integer &&
json?["y"]?.Type == JTokenType.Integer)
{
return new Point((int)json["x"], (int)json["y"]);
}
return null;
}
The check against JTokenType.Integer is just to avoid a casting exception. The null checks are just to avoid null exceptions. I wonder if the compiler could ever handle something like 'this if you can, else null', without actually having any exceptions getting throw and caught underneath: public static Point FromJson(JObject json) =>
return new Point((int)json["x"], (int)json["y"]) ?: null;A big nope from me.
Nicer visual representation is OK.
Changing syntax based on visual attributes it's not.
http://blog.jetbrains.com/idea/2009/03/closure-folding-in-in...
You might find this interesting if you're thinking along those lines: http://joshondesign.com/2014/08/22/typopl
So what happens if you open the file in a different editor?
Anybody have a pdf version?
I'm tempted to use C# in the future again. Using it on Windows has always been good - and now that it compiles to native code too and that the libs are open....
"Will Server/Desktop apps benefit from .NET Native and/or the Compiler in the Cloud?
Desktop apps are a very important part of our strategy. Initially, we are focusing on Windows Store apps with .NET Native. In the longer term we will continue to improve native compilation for all .NET applications."
http://www.hanselman.com/blog/AnnouncingNET2015NETAsOpenSour...
Unless Windows Desktop is meant as store applications.
var first, last = parseName(fullName);
Instead of: String last;
var first = parseName(fullName, out last); return Tuple.Create(foo,bar);
Should be: return (foo,bar);
The worst part is using the Item1..ItemN properties. One way I've gotten around it is to create a Tuple extension method called Apply [1]. I allows you to do this: ParseName(fullName).Apply((first, last) => ... )
That allows for giving names to the tuple ItemX fields and uses them 'in scope'.At least with C#6 we can now open static classes like namespaces and do something this:
using Language.Helpers [2]
...
return tuple(x,y);
Which already makes it start to feel like it's part of the language. ParseName(fullName).Unpack(out string first, out string last);
However, this makes for essentially left-to-right assignment, which is contrary to the usual order. So this creates discontinuity when moving from one return value to two return values.By the way, creating a new variable half-way down a method is also creating a new scope (the variable isn't in scope above the declaration, and it is in scope below it, until the end of the method).
For example:
public int GetSurnameLength()
{
string fullName = ReadFullNameFromDb();
Tuple<string,string> result = ParseName(fullName);
return result.Item2.Length;
}
Has the same effect as: public int GetSurnameLength()
{
string fullName = ReadFullNameFromDb();
return ParseName(fullName).Apply( (first,last) => last.Length );
}
The only real downside to the Apply method is the syntax clutter from the closure. But there's no real issue with scope as far as I can tell (because the rest of the method can be within the closure if necessary). This is very similar to how 'let' works in F#. Tuple<string, string> fullName = ParseName(fullName);
var firstName = fullName.Item1;
var lastName = fullName.Item2;that second example is always a bad choice and i would never but i do agree a little tuple support would be nice as a trap door kinda feature to avoid code like this
Either first-class tuples or anonymous classes as return types would reduce this cognitive overhead.
No. C# is an object-oriented language. It doesn't have functions, it has methods. Methods are always attached to a class. Even anonymous methods (lambdas) are compiled to be a method on a class (like c__DisplayClass1).
"Bare" or "global" functions have no place in C#.
I get that the CLR expects a certain way of implementing things. But your own example of Lambdas are an excellent example of how we can use syntax to overcome bureaucracy in the runtime, or else we would be stuck in Java land with anonymous classes implementing interfaces.
Ultimately, it's all sugar. If a static method of a static class can be made to look like a function in calling code, then it makes sense to make it look like a function in the definition.
Classes (in typical static, class-based "OO" languages like C++/Java/C#) aren't objects, and static classes are classes that don't even relate to objects the way that "normal" classes do. Static classes as containers for functions aren't papering over object-oriented bureaucracy that "everything is an object", they are papering over class-oriented bureaucracy that "everything is connected to a class".
(This is a general agreement with your basic point, though.)
https://github.com/MiniProfiler/dotnet/blob/master/StackExch...
They're extremely useful and intuitive string helper methods. Truncate(), IsNullOrWhiteSpace(), etc are things I use daily. And while you can type string.IsNullOrWhiteSpace(string) that is annoying and counter-intuitive.
I agree that Truncate would be a nice one to include in the core.
Look at what the helper actually does. I already addressed this in my comment.
string hello = magic();
if(hello.IsNullOrWhiteSpace())
{ ... }
Is significantly more intuitive than: string hello = magic();
if(string.IsNullOrWhiteSpace(hello))
{ ... }
Plus it is consistent with things like Contains("XYZ") (e.g. hello.Contains("something")).Truncate is useful just because Substring() throws a bunch of dumb exceptions. It is mostly a workaround for Substring's poor design.
Since this would be completely broken if it were an instance method, the reader might be surprised at first until they realize it's an extension method. So all I'm saying is that it's no less "counter-intuitive" than the normal string.IsNullOrWhiteSpace.
I've also wanted a system similar to dependency properties in WPF that was a little lighter weight. DPs do pretty much everything i could ask for from change notification to binding to pluggable validation, I just wish they we not so tied into the WPF code so i could apply them to my data layer.
[1] http://devblog.guidewire.com/2011/03/03/feature-literals/
I don't use C# anymore (job change, not out of dislike), but I was always really happy working in it. I'm still not a huge fan of Windows, but C# is a wonderful language.
I also expect that a large fraction of applications never gets localised (in-house tools, scientific software, etc).
In total, I think there are orders of magnitude more lines of message formatting code that do not get translated and likely never will be translated.
It appears modern language designers think it worthwhile to make life for that use case a bit easier.
(it is not that the code gets much shorter, but more that, for true translation, you have to move the format string into a resource, and load it from your code)
I'm a little worried about "nameof" in the hand of amateur programmers though. Efficiency aside (because it's not efficient), code readability might take a hit.
As others have said, I'd therefor expect this to be a purely compile-time feature that just inserts the name of the reference within. The whole reason for this keyword seems to be that you have no string ("foo") but a reference/name instead (foo). Which can be picked up easily by tools.
nameof(foo) <=> "foo"
Efficiency doesn't change
Oh those poor, poor souls who have had to work in C#'s shadow.
That being said, I hope that all the open-sourcing is going to make it available where I really want to use it - Unity, for instance. (Disclaimer: I'm an open source dev @ Microsoft)
And we'll see how long it takes Unity to actually support the current C#. My guess would be a couple years, since Unity 5 isn't even out yet, and there's usually 18 months between major releases.
I'm fond of a pattern where error codes can be implicitly converted to Exceptions[1].
It's often argued that exceptions are for things that your program cannot handle and error codes are for things that it can. But, in my experience, whether or not a bad condition is an error or an exception depends upon the layer in which the code lives.
Also, a side benefit of this scheme is that most of the exceptions show up in the class browser, or can be explored through reflection.
[1]https://gist.github.com/noblethrasher/ba37ed6176ebeb679dd2 -- In my example, the error code is an integer, but it could be another class that holds more information about the operation.
I mean - I'm saying this as somebody who hasn't done a lot of C# or .NET work in the last few years, but think about what you would have to do if you had to implement this in a safe and bug-free way.
The elvis operator is useful to. Makes me think sticking to F# will cause fewer classes of bugs that can happen in C# (the onChanged example is quite interesting).
I also love the ?. operator.