This will be my last post before I head off for my annual vacation in Canada; see you again at the end of August for more Fabulous Adventures in Coding!
Last time on FAIC I suggested a rule for translating nested “from” query expressions into a much simpler form than the C# specification requires. Why does the C# specification not use my simplified form?
In fact what I showed yesterday is pretty close to what the LINQ translation rules for
SelectMany queries looked like shortly before shipping C# 3.0. The problem with it becomes apparent when you consider the following: Continue reading
A query expression in C# is, as you probably know, just a syntactic sugar for a bunch of method calls. For example,
from customer in customers
where customer.City == "London"
is a syntactic sugar for
Where(customer => customer.City == "London").
Select(customer => customer.LastName)
A great many queries are straightforward variations on this pattern: the query is translated into a series of method calls where the arguments are lambdas formed from the range variables and expressions in the query. However, some of them are weird. This one is straightforward: Continue reading
Last time on FAIC I described how language designers and compiler writers use “lowering” to transform a high-level program written in a particular language into a lower-level program written using simpler features of the same language. Did you notice what this technique presupposes? To illustrate, let’s take a look at a line of the C# specification:
e as T produces the same result as
e is T ? (T)(e) : (T)null except that
e is only evaluated once.
This seems bizarre; why does the specification say that a higher-level operation is exactly the same as a lower-level operation, except that it isn’t? Because there is no way to express the exact semantics of
as in legal C# in any lowered form! The feature “evaluate a subexpression to produce its side effects and value once and then use that value several times throughout its containing expression” does not exist in C#, so the specification is forced to describe the lowering in this imprecise and roundabout way.
A nice principle of programming language design that C# does not adhere to is that all the higher-level features of the program can be expressed as lower-level features. Why is this nice to have? Well, not only is it a big convenience for writers of the specification, it also is a big convenience for writers of language analyzers. If you can programmatically transform a high-level language into an exactly equivalent program in a language with far fewer complicated concepts then your analyzer gets simpler. Continue reading
Programming language designers and users talk a lot about the “height” of language features; some languages are considered to be very “high level” and some are considered to be very “low level”. A “high level” language is generally speaking one which emphasizes the business concerns of the program, and a low-level language is one that emphasizes the mechanisms of the underlying hardware. As two extreme examples, here’s a program fragment in my favourite high-level language, Inform7:
Hey there fabulous readers: I’d like to get your opinions on unchecked exceptions.
Before you run off down to the comments and start typing a short novel, I want to make sure that we’re all on the same page here. Continue reading