Today at lunch, a few of my colleagues got into a discussion of the merits of some of the new language features in the .Net family. Unfortunately, I was at the wrong end of the table to participate in the discussion, but it has spawned an article that I want to respond to. Go take a look at it, then come on back.
To distill Ben’s thesis, he’s “annoyed that many of these ‘cool’ language features in C# are nothing more than libraries in Smalltalk”. I can understand his annoyance. C# is being touted for having new, innovative language features while languages like Smalltalk get relatively little attention despite having similar features (though usually as a part of a library) for years.
Ben goes on to show how C#’s ?? operator (which returns the left expression if that expression is not null, and otherwise returns the right expression) can be added very easily to Smalltalk.
I guess this is why, despite all of its faults, I have a lot of trouble giving up on Smalltalk. C#’s a good language, and .NET’s a good framework; but I cannot help but feel that this isn’t an issue of reinventing the wheel, as much as forgetting that we can provide programmers the tools to make their own types of locomotion.
Unfortunately, I think he is missing the bigger point. I do not disagree that giving programmers the ability to “make their own locomotion” is important. It is, in fact, completely necessary if you want a language to have useful libraries. But it is also a virtue when languages make it unnecessary to create a new five wheeled vehicle.
And we’ve been there before. There was a time when language designers seemed to think that a good language implemented a minimal set of features. And from that mentality we got languages like C++, which couldn’t even go as far as implementing a native string type. In fact, there are so many that people have created comparison pages to help you figure out which one to use.
So while I can understand his frustration that Smalltalk hasn’t gotten the same attention as .Net for features that are trivially implemented, I feel that his argument is analogous to saying that I should not be excited about Python having a built in string type because C++ has always had the ability to implement one.
That’s something of a strawman argument, in two directions.First, C++ is exactly the wrong comparison to make. The language’s syntax implements every single feature under the sun. Templates, classes, structs, multiple dispatch, generics, static typing, dynamic typing, default and optional parameters, it’s all there. Further, C++ actually has massive standard libraries to complement its massive syntax. Stacks, queues, linked lists, dynamic arrays, static arrays (both with and without bounds checking), maps with whatever backing you want. It’s overflowing with syntax and libraries. It so happens there’s one construct–strings–that C++ should have interned and was not. Yet the language itself has more built-in syntax and more built-in libraries than you can sneeze at.And it’s still a festering pile.There were many data libraries before LINQ to SQL for .NET, including Subsonic, NHibernate, and direct ADO.NET access, and there will be many after. You still have to pick between them, and none are the be-all end-all official solution from Microsoft at this point. They all would have benefited from having a LINQ-like syntax in C#. Yet only Microsoft could add LINQ to the language; the rest were forced to use syntax such as database.Select(“column”).In(“table”).Where(“foo = bar”), which is uglier, less type-safe, and arguably more confusing. No one’s benefiting from this; everyone’s losing.The real issue you’re highlighting is that languages should be the bare minimum that they have to be, *but no less.* Smalltalk has an incredibly rich base language. It also has a very simple syntax that makes it very easy to extend that base language. C++’s base language is, at various points, far too small and far too big. That doesn’t obviate my argument, as much as attack C++ for the failure it ought to have been.
I do agree with you when you say that it’s great that a language evolves and does not FORCE us to invent a new five-wheeled vehicle. That’s perfect.I have to say, though, that we could have both. Give us the means to make our own “type of locomotion” AND evolve the language to include the ones that seem more useful.The thing is that, when the language itself allows for extension, as it seems Smalltalk and other languages do, “evolving the language”, in this sense, is a matter of including these libraries in the standard library. Which is usually much easier than changing the language specs or the compiler, I think.Great post, by the way, as is your colleague’s.
I specifically dislike the string class example. If the language itself supported a string type natively, the only reason you wouldn’t have to compare various string classes is because people wouldn’t think to do so — not because the native implementation would be the best.
@BenjaminIf have listed a bunch of features as being part ofC++ that are not part of C++.Namely: multiple dispatch, dynamic typing, optional parametersAnd also the standard libraries are very narrow when compared with C# or Java.That said, I see your point.
I am excited about simpler ways to do the things I frequently need to do. This is true whether they are a language feature or a library feature. General tools are useful and so are specific implementations.Any LINQ specific syntax adds complexity compared to an equivalently powerful construct built as a library.Smalltalk has a simpler and more powerful core language than C#.I have not found a Smalltalk implementation I want to use.
The use of C++ is of great value in certain cases. If you feel that you need dynamic typing all the way and always you probably have a serious design problem. Also I would suggest that you read the final draft for C++0x. I bet that you will find a series of constructs that allow you to have what you say as “not existing in C++” anyway.Then again, cool programmers write everything in assembly because it makes them look smart.Bottom line: languages are tools. Never assume that language A is superior to language B under any circumstance. You would then only be using the wrong type of screwdriver.
@Benjamin – I don’t think C++ is a strawman at all. The things you listed are all intended to allow you to extend the language further, but with little actual use to many programmers. It took a dedicated team to put together the STL. That said, C++ is lacking some extensibility features that would have made the language much nicer to work with, which makes the example weaker.My main point is that, given the choice between an extensible language and a batteries-included language, the batteries-included language will win me over every time. It’s cool that I can write 2009 Smalltalk in 1980 Smalltalk, but as a professional software developer, that doesn’t really do me any good. I would much rather have a language that lets me create real software than having a language where the language designers expected me to implement the language features as libraries before I could write real software.Think about it. The new popular languages (C#, Python, Ruby) and frameworks (ASP.Net MVC, Django, Rails) all take this batteries-included approach, and because of that, they’re winning.
There’s a difference between features implementated in the standard library and features implemented as part of the language *itself*. The batteries included part of Python, for example, is mostly implemented *as* libaries *using* Python. For example, abstract base classes.