Phil Trelford's Array
POKE 36879, 255

Walkie Scorchie

September 7, 2013 16:58 by phil

From the window at the office I’ve seen a series of futuristic buildings erected, first the Gherkin, then the Shard and now the Walkie Talkie:

London skyline 

The last one being recently been re-dubbed the Walkie Scorchie as it produces a supercharged solar ‘death ray’ that has burned holes in carpets, melted furniture and even the interior of a Jaguar parked nearby.

It feels almost reminiscent of the dystopian future portrayed in the cult film Idiocracy:

Idiocracy skyline

Though our current society is probably closer to the surveillance society of 1984 with the omnipresent Big Brother watching over you:

Big brother is watching you

The everyday software we work with is no less broken, or so Scott Hanselman concludes in everything's broken and nobody's upset.

Software is increasingly a world of broken windows where developers are more accustomed to working around issues than giving feedback, let alone tackling the root causes.

waiting for background operation to complete modal dialog 

Anyone else struggling with the cognitive dissonance of a modal dialog waiting for a background operation to complete?

XAML

I’ve been using XAML in it’s various guises off an on for over 5 years now. Over that time I’ve used WPF, Silverlight and Metro. It feels like little has changed in that time. It’s still probably the best thing out there for desktop app development but surely we could do better.

XML

I’m still stuck editing views in XML, the poor man’s DSL. I, like the developers I know rarely use the designer view. When we do it frequently hangs and we’re left manually killing XDescProc.exe from task manager.

Data Binding

Data binding is central to XAML. With it you can easily bind a collection to a data grid and get sorting and filtering for free. But binding comes with a high performance cost and it’s stringly typed nature means you’re left finding binding errors in the output window at runtime.

Dynamically binding a view to a model would make more sense to me if I could edit the view at runtime, but you can’t, it’s compiled in.

Value Converters

If I want to transform a model value bound to the view to a different form I have to create a class that implements the IValueConverter interface then reference it as a static resource in the resources section. It has all the elegance of C++ header files. Achieving the same thing in ASP.Net is much simpler, you can just write inline some code in the view or call a function.

INotifyPropertyChanged

There’s a plethora of libraries and frameworks dedicated to working around this design decision, from the MVVM frameworks with LINQ expressions to PostSharp and attributes. The C# 5 compiler’s CallerMemberName attribute has finally brought some sanity to the situation. But I know many developers, including myself, have wasted countless hours dealing with it and trying to think of ways of subverting it.

Just about every view model class ends up inheriting from some ViewModelBase or ObservableObject class so that it can implement INotifyPropertyChanged.

Inheritance

It is often said that object-oriented programming is well suited to graphical user interfaces. Perhaps, but I start to have doubts when I see WPF’s Button class with 9 layers of inheritance and over 160 members.

Visual Studio 2010 introduced improved intellisense with substring search on members to partially work around this, but honestly I’d prefer to see buttons be closer to having content and a clicked event than their current diaspora of responsibilities.

Null Reference Exceptions

By far the most common error I see in C# applications is Null Reference Exceptions. Hardly a day goes by where yet another null check is added to the codebase. This needs to be fixed at the language level, functional-first languages like Scala and F# show it’s possible.

HTML5 & JavaScript

HTML 5 and JavaScript are now being pushed as an alternate environment for desktop development. JavaScript has come a long way performance and libraries wise and I like the HTML 5 Canvas model. However I’m not yet convinced how well this scales to multi-window applications that need to interact between processes.

Windows 8

I get that Metro style interfaces are good for tablets and touch, but for multi-window desktop applications it feels like a non-starter.

 

I’ve seen traders use 9 displays simultaneously, running a multitude of different apps from execution platforms and news services to Excel, Outlook and instant messengers.

To me Windows 8 appears to be consumer orientated release. I’m hoping the next version will bring something for the larger customer base of business users.

Vendors

One person’s problem is another’s opportunity. Third party vendors like JetBrains are grasping the opportunity with both hands by patching flaws in Visual Studio and C# with tools like Resharper. They’re now starting to provide elastoplasts over XAML editing too. Jetbrains are not the only ones, Telerik and others are making hay selling themes and datagrids.

627 

To temporarily workaround performance issues caused by the cost of the mouse handler events in one these products we were forced to throttle the number of system mouse events bubbling through the system.

Duct tape is a good short term solution, but surely at some point we should consider building a stronger foundation.

Simplicity

I would not give a fig for the simplicity this side of complexity, but I would give my life for the simplicity on the other side of complexity. - Oliver Wendell Holmes, Jr.

XAML is huge and bloated, WPF 4.5 Unleashed is 864 pages long, yet XAML’s focus on data binding makes it feel like a one-trick pony.

I think a modern desktop UI environment needs to cover a diverse range of product scenarios. There should be a low-level core that can be easily accessed with code for high performance features all the way up to a designer view for tacking databases on to views, and it should all interoperate seamlessly.

Sections of the development community are striving to bring simplicity to our environments. Language designers like Rich Hickey (Clojure) and Don Syme (F#) are bringing us simplicity at the language level. I’d love to see these thought processes applied to UI environments too.

To tackle the root causes of problems some times you need to stop continuously patching over the cracks, step back and take time to look at the big picture. To create Clojure Rich Hickey practised Hammock driven development. I’d love to see more of this kind of thoughtful design and less Mortgage driven development.

Tackling the root causes of complexity and defects in our software is not an easy choice, it requires investment and changes to the way we do things. But not changing is a choice too.

They live out their lives in this virtual reality as they would have around the turn of the 20th and 21st centuries. The time period was chosen because it is supposedly the pinnacle of human civilization. – Agent Smith

Must Java like languages and XML be considered the pinnacle of software development for time immemorial?


Tags:
Categories: Architecture | WPF | Silverlight | WinRT | .Net | C# | JavaScript | Scala | F#
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

A single line stack trace

August 13, 2012 00:23 by phil

This week I was assigned a bug with a single line stack trace:

Telerik.Windows.Controls.RadDocking.<>c__DisplayClass1b'::'<DropWindow>b__19
 

The exception type was of type NullReferenceException. The issue could be reproduced by repeatedly docking and undocking a window in the application for about 30 seconds. The result was an unhandled exception that took down the application.

The single line indicated that the exception originated somewhere in Telerik’s RadControls for Silverlight, probably a compiler generated class for a closure.

Ildasm

Ildasm is a tool that lets you look at the .Net IL code generated by the compiler. Looking at the Telerik Docking dll with Ildasm, the generated class and method can be seen:.

IL DASM - Telerik.Windows.Controls.RadDocking.c_DisplayClass1b

DropWindow_b_19

.method public hidebysig instance void 'b__19'() cil managed
{
 // Code size 18 (0x12)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: ldfld class Telerik.Windows.Controls.RadPane 
  Telerik.Windows.Controls.RadDocking/'<>c__DisplayClass1b'::activePane
 IL_0006: callvirt instance class Telerik.Windows.Controls.RadPaneGroup 
  Telerik.Windows.Controls.RadPane::get_PaneGroup()
 IL_000b: callvirt instance bool [System.Windows]
  System.Windows.Controls.Control::Focus()
 IL_0010: pop
 IL_0011: ret
} // end of method '<>c__DisplayClass1b'::'b__19'

The IL code shows a PanegGroup property being accessed followed by a call to a Focus method. The c__Displayclass class name indicates a closure.

Source Code

Telerik’s source code contains a RadDocking class with a DockWindow method that contains a closure that calls SetFocus on PaneGroup. Bingo!

Dispatcher.BeginInvoke(() => activePane.PaneGroups.SetFocus());

Workaround

The workaround is a common one in C#, add a null check against the property (PaneGroups) before calling the method (SetFocus).

What can we learn?

This fatal exception was found in a third party framework, thankfully during development. Lets examine how this happened and what can be done

Null checks

Tony Hoare, inventor of QuickSort, speaking at a conference in 2009:

I call it my billion-dollar mistake.

The billon-dollar mistake is the invention of the null reference in 1965.

C# references are null by default, and nullability is implicit.

Are null references really a bad thing? – Top Answer on Stack Overflow:

The problem is that because in theory any object can be a null and toss an exception when you attempt to use it, your object-oriented code is basically a collection of unexploded bombs.

How could this be done differently?

In F# references are not nullable by default, and nullability is explicit via the Option type, i.e. this issue could be removed by design.

Mutation

The PaneGroup property is most likely initialized with a valid reference before the call to BeginInvoke. The BeginInvoke method adds the Action to a queue and call it some time in the future.

C# objects are mutable by default.

This means that the state of the PaneGroup property may be mutated (set to null) before the closure is called.

F# objects are immutable by default, i.e. this issue could be removed by design.

BeginInvoke

It looks like SetFocus is being called asynchronously as UI Duct Type to workaround another issue where focus can not be set until the control is initialized:

It’s a standing joke on my current Silverlight project that when something isn’t working, just try Dispatcher.BeginInvoke.

This issue would require a framework fix where you could specify the control that receives focus by default.

Asynchronous calls

As the call to the closure was asynchronous it would be added to a queue, and later processed. The act of adding the closure to the queue removes it’s calling context which makes debugging hard.

Conclusions

Just this single line stack trace demonstrates a cacophony of language and framework design issues. Nullability by default in C# makes code look like a collection of unexploded bombs. Add asynchronous calls to the mix and you have even more chances of triggering one of those bombs. Worse working around the framework often forces you to make asynchronous calls to workaround other issues. Finally when a bomb does go off you are left with very little information to diagnose it.

Is OOP really a good paradigm for modern asynchronous UI programming?


Tags:
Categories: C# | F# | .Net | Silverlight | WPF | WinRT
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Pacman Tiles

July 22, 2012 10:11 by phil

Back in January I built a sample Pacman maze script in F# to use at a Pacman Kata evening with the F#unctional Londoners group. Coincidentally there’s another Coding Kata this Thursday 26th July at Skills Matter. Anyway a couple of weeks ago I started playing with the sample again on the train to and from work, filling in some of the gameplay.

You can play the latest version with your cursor keys and 9 lives below:

(Right click to install game to desktop)

 
Windows 8

As the sample runs in Silverlight I thought I’d also try it out on it’s cousin WinRT. WinRT lets you build Metro apps on Windows 8. The transition code wise has been pretty straight forward and I now have a tile for the game appearing on my Windows 8 start page:

One click: From Metro tile to video game

 

WinRT is yet another XAML based framework, and is very similar to Silverlight and WPF. One of the few differences I have encountered has been the namespaces the classes are in. For example in Silverlight the Canvas class is in the System.Windows.Controls namespace and in WinRT it is in Windows.UI.Xaml.Controls namespace. It is possible to target both WinRT and Silverlight from the same source code using conditional directives:

#if NETFX_CORE
using Windows.UI.Xaml.Controls;
#else
using System.Windows.Controls;
#endif

 

Multi-targeting

Multi-targeting Silverlight and WinRT is the route I decided to go down which allowed me to develop the game on my laptop running Windows 7 with Visual Studio 2010. Then I periodically tested it out on a desktop box running the Windows 8 Preview Release using Visual Studio 2012. Visual Studio 2012 does run on Windows 7, however WinRT does not.

The WinRT version of the app is implemented in F# and C#. The game part is written in F# as a portable library and the plumbing in C#. There’s a great walkthrough on Creating a Portable F# Library over on MSDN which describes this direction in some detail.

Code Fragment

When the ghosts are eaten they need to return to the enclosure. I used a flood fill algorithm to mark the shortest route from anywhere in the maze back to the enclosure. The flood fill is started inside the enclosure, the fill number is incremented with each iteration of the fill, so that the shortest route is to follow the lowest number adjacent to the ghost’s current square:

module Algorithm =
    let flood canFill fill (x,y) =
        let rec f n = function
            | [] -> ()
            | ps ->
                let ps = ps |> List.filter canFill
                ps |> List.iter (fill n)
                ps |> List.collect (fun (x,y) -> 
                    [(x-1,y);(x+1,y);(x,y-1);(x,y+1)]
                )
                |> f (n+1)
        f 0 [(x,y)]
 
Full Source

The full source code to the game is publicly available on BitBucket:

A single file playable script version is also available on F# Snippets: