I’ve been down in the laboratory since my last post and I’m back with a brand-new prototype. I was working on scripting the first video for this prototype when I realized there’s just a lot of context to set beforehand so I’m taking a break to write a quick introduction.
What do I mean by pattern-based?
When I describe a language feature as “pattern-based” I mean that the feature is designed to work with any code that fits some pattern the compiler knows about rather than a specific limited predefined set of types. Not every feature is pattern based in VB.NET but several of them are. For example:
`For Each` doesn’t require a type implement `IEnumerable` (or that `IEnumerable` even exist) but rather that it meets the Collection pattern. A type is a Collection Type from the perspective of the compiler/language if it has an accessible `GetEnumerator` method that returns a type with a Boolean returning `MoveNext` method and a readable `Current` property and the `Current` property determines the type of the elements of the `For Each`. None of this requires `IEnumerable`, that’s just convenient and it means that library authors can write specialized enumerators which are more efficient in some way, usually by being structures rather than classes.
`Await` is another example. Everyone knows you can await `Task` and `Task(Of T)` but the language doesn’t require that, rather that the type have a `GetAwaiter` method that returns some type with the right set of members on it. If the type meets that pattern it is considered Awaitable. An example of this in action is the `Task.Yield` method which returns a `YieldAwaitable` structure, rather than `Task`.
Query comprehensions (the SQL-like LINQ syntax) aren’t tied to `IEnumerable` or even the `System.Linq.Enumerable` type either, but rather work on Queryable types—types which have a `Select` method that take a delegate that itself takes 1 parameter, the type of which is the element type of the `From` operator and may have other operators like `Where`, etc.
A big win from the pattern approach is that often a type can be made to support a pattern after the fact through an extension method. This is great when you don’t control the library that type is defined in but still want it to work well with new features. C# and F# also use this approach at times to varying degrees (F# turns it up to 11, actually). There are other features that use patterns (and ones that don’t) those are some big examples. Eric Lippert (of course) talked about some examples on his blog and one of the ones that don’t in either VB or C# (occasionally to my chagrin), the `Using` block.
Right now, XML Literals are in the ones that don’t bucket and I’m looking at what possibilities open up if that changes. These first three scenarios are minor. I definitely thought about them but I understand if they’re not top of mind of a lot of other people. They were stops along the train of thought. The last two though are pretty major so feel free to skip ahead if you aren’t interested in trivia.
Windows Runtime/UWP XML
One of the first concrete scenarios I had was back when I was exploring the Windows Runtime/UWP library and I noticed that WinRT defines its own `Windows.Data.Xml.Dom` namespace which is, of course, not the `System.Xml.Linq` namespace that VB XML literals work with and I got to thinking, wouldn’t it be nice if VB could work natively with the WinRT types. If you look at the docs for creating live tiles and sending tile updates, the whole tile template system in Windows 8.x/10 is built on XML and their code examples look like they would benefit from XML literals and XML axis properties.
That’s one idea. It’s good language hygiene but fairly limited.
Rich WPF Message Boxes
I’m a big fan of Alan Cooper “Father of Visual Basic” (big surprise) and specifically his books on user experience like “The Inmates Are Running the Asylum” and “About Face: The Essentials of Interaction Design”. In one of those books he talks about message boxes and points out the ways software provides poorer, less situationally appropriate experiences because the default APIs are “good enough” and programmers just try to squeeze whatever problem they have into what the API provides rather than writing a custom dialog. It’s been years but I recall him showing an example of some program that wants the user to do one of two things and it puts up a dialog box that says something like “How would you like to proceed? Click ‘OK’ to file your taxes jointly or ‘Cancel’ to file separately with a 1099c extension”. Obviously, this choice shouldn’t be in terms of ‘OK’ and ‘Cancel’ but the programmer was too lazy to write the custom one-off dialog. The programmer has delegated mapping concepts from user-domain to the API to the user and that sucks.
The MessageBox.Show in WinForms and the other one in WPF are a little bit more customizable than this but sometimes I call MessageBox.Show and think “I wish I could provide a formatted string as the dialog text, maybe include some bolding or color or an image but the API just takes a string”. Ideally I’d be able to use all of WPF’s TextBlock primitives and just hand that to a generic built-in dialog presenter. I could write one, of course but there’s still some tedium to it because in my code I can’t use XAML, I have to imperatively construct a potentially elaborate object graph and that stinks.
If you look at the unit tests in the Roslyn source code, you’ll see thousands of examples of things like this:
The test team created these DSLs for setting up tests for the compiler and the IDE that other code then parses to create the actual test environment. XML has just enough structure vs strings while being flexible around multiline content. It’s neat and in a lot of places convenient to use XML to describe these test cases declaratively but it’s unfortunate that everything that happens in the XML literal is opaque to the compiler so you don’t get any tooling assistance at compile time. You could help this a little with analyzers but there are still seams in the experience.
In an earlier post I showed you how one could use XML literals to make a basic view engine for ASP.NET Core. It was nice but because it’s just producing an anemic XML DOM there are some limitations on how kick-ass it could be. I’m trying to see how far I can take it.
On the other side of the spectrum we have Xamarin.Forms. I’ve been interested in Xamarin for a few years now but one thing that bugs me is that to use it in VB I have to use code to construct my UI. I can’t use my XAML skills (until now).
So, I made a prototype…
The challenge is, can I come up with some reasonable pattern that would enable an XML literal to construct and/or interact with things other than the XLinq API. I’ve got a first-draft and some notes and a about 2-3 scenarios to show you based on what I came up with that I hope you’ll like. The first one up is the Xamarin scenario and it’ll be the subject of my very next post. I just wanted to get all the background out of the way so I can focus the video and the blog post on the scenario itself rather than general context setting.