It seems the sneak peek at “for expressions” in my previous post caused quite a bit of stir, so i figured i would spend a few minutes talking about the new expression types in general.
As you probably know, if you ever stopped to think about Pascal grammar, the most basic component that makes up a method body is a statement. A method body is pretty much defined as a list of statements, separated by semicolons.
x := 5 is a statement.
MyObject.DoSomething is a statement. Even a
end block is a statement (containing, nested within itself, another list of statements).
There’s a special kind of statements that seen frequently, and that are expressions. An expression is a statement that has a value, and as such, can be used in any code construct that expects a value – such as on the right side of an assignment, within arithmetic formulas, or as parameter to another method, for example.
5 is an expression. so is
(In early Pascal, expressions did not use to be full statements. For example, functions (ie, procedures that return a value) could not be called without making use of that return value. In other words,
sqrt(9) was not a valid statement, although
x := sqrt(9) was. But that’s a thing of the past).
Where am i going with all of this? Well, with the upcoming Spring 2011 release of Delphi Prism, we have extended the language. We took three commonly used statements, and we turned them into expressions.
This was done as part of an effort to bring more functional programing concepts to the language. Functional programing has been a niche in commercial software development for a long time, with most of the limelight going to (first) procedural and (later) Object Oriented programming, the latter of which is sort of a natural evolution of the first.
Functional programming uses a quite different paradigm, but it turns out that it is a very good fit for writing efficient multi-threaded code, and that’s why functional programming has been seeing a big revival over the past year or so, with developers looking at Erlang or Haskell. Microsoft has also stepped up its work on F#, a functional language for .NET, and is including that as a first-tier language in Visual Studio 2010.
For Prism, we decided to take a slightly different approach, and see if we could – over time – extend it with elements from functional programming languages, but, as has been the goal with Prism from day one, keeping them in line with traditional Pascal syntax and feel. (F#, for example, has many interesting concepts that make for a powerful language – but a god-awful and near-incomprehensible syntax to go along with them).
Our new expression types are a first step in that direction, so let’s have a look at them:
“if” statements are the bread and butter of just about every pascal method, allowing the conditional execution of one of two statements, depending on a boolean condition:
|if Condition then ThenStatement else ElseStatement;|
We have extended this syntax to allow the entire “if” clause to become an expression, if the statements it contains are expressions, as well. in other words, you can now write
|if Condition then ThenExpression else ElseExpression;|
|s :='The Condition is '+if Condition then'true'else'false';|
|var x :=if Condition then3;|
The same extension applies symmetrically to “case” statements. A case statement where each individual case is an expression becomes an expression itself. As with the “if” expression, the type will be the determined by lowest common denominator of all the contained expressions, and if no else statement is provided, it will be nullable.
|s :=case Number of1:'One';2:'Two';else'Many';end;|
The last new type of expressions i want to talk about are “for” expressions. As with the other two, we have taken the regular “for” loop statement, and enabled it to be an expression:
|foreach x in SomeSequence yield Expression;|
|for x := StartValue to EndValue yield Expression;|
If this sounds familiar from another feature in Delphi Prism called iterators, then that is no accident. A “for” expression has very much the same attributes and behavior of an iterator – in fact, you could think of them as “anonymous iterators”.
So what is the value of a “for” expression? The mentioning of iterators and the use of the yield keyword may have given it away: the value of a “for” expression is a sequence containing each of the individual expressions.
|var SomeNumbers :=sequenceof Int32; SomeNumbers :=for i: Int32 :=0to100yield i*i;// SomeNumbers contains the squares of 0 thru 100|
To give an extreme example it’s entirely fine to declare the following
|var AllInts :=for i: Int64 :=0to Int64.MaxValueyield i;|
|foreach x in AllInts index i dobegin// only handle first thousand items. else we'd be at it forever.if i < 1000thenbreak; Console.WriteLine(x);end;|
And that’s the new expression types, one of many new features in the upcoming Spring
20112010 release of Delphi Prism. If you’re part of the field test (and if you’re an active Delphi Prism customer, you really should be!), you can see these in action in the current beta drop.
Let me know what you think, and stay tuned for more!