Pattern-Based XML Literals Prototype: Introduction

Hey all!

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.

Why?

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.

Minor Scenarios

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.

XML-based DSL’s

If you look at the unit tests in the Roslyn source code, you’ll see thousands of examples of things like this:

An actual VB compiler semantic unit test from the Roslyn code base
An actual C# IDE unit test written in VB, presumably to take advantage of those sweet sweet XML literals

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.

Major scenarios

ASP.NET Core

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.

Xamarin.Forms

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.

Regards,

-ADG

3 thoughts on “Pattern-Based XML Literals Prototype: Introduction

  1. Pingback: Pattern-Based XML Literals Prototype: Cross-Platform Mobile Apps w/ Xamarin.Forms | Anthony's blog

  2. Pingback: Pattern-Based XML Literals Prototype: ASP.NET Core Revisited | Anthony's blog

  3. Pingback: Pattern-based XML Literals Prototype: Client-Side VB.NET Running in the Browser (sorta) | Anthony's blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s