The Pedagogy of the Puzzles

My recent blog post illustrated the questions and answer format I use in my Pluralsight course .NET Puzzles, Gotchas and Cautionary Tales. At the end leaves it leaves a question open for the reader. I got this comment from James Curran:

arrg… You got me.

I was SURE that while string-plus-int concatenates,  int-plus-string was a syntax error.

Ah, James, you fell into my trap. Flying blissfully along you caught sight of the dew on the web and flew right into it…

In five years, long after I’ve forgotten what I posted, you’ll encounter me and say “2 + 4 plus an empty string is six as a string.” In ten years, you’ll be working in a language called Xinx and you’ll say “I wonder…add string and integer…order of operands…” Maybe you already tried something similar in JavaScript or TypeScript or Visual Basic…

The Power of the Puzzle

The power of the puzzle isn’t in the question and the answer I give. If you watch my course or read my previous post and never stop the video to think, write down your answer, or experiment in Visual Studio… well, you might think you knew the answer when you didn’t.

The power is in making you think about a particular detail of .NET. Think. Fear slap. Remember.

You’re wired to think you’re correct. This is extremely helpful if you catch a peripheral view of an eye that looks like a tiger’s eye. Looking back over your shoulder at a dead run, the same odd rock in the bushes is still a tiger.

But tigers don’t sit in bushes quite like that. After a bit you pause and tentatively go back. You find that odd rock. And you will never forget that there is a rock that looks like a tiger’s eye beside the new trail, in the morning, in the spring.

You aren’t wired to learn .NET. You’re wired to learn about tigers and which plants are poisonous to eat. And amazingly, you’re wired to build a complex framework from which you can speak, think, make additional projections and learn very complex things. Congratulations, you’re a human!

But learning theory says you’ve got to get a little slap, be a little upset to learn. Laughter, fear, trauma, and black and white “Crap, I’m wrong”. Otherwise, your brain is wired to say “yeah, yeah, got that.”

In fact, if the idea is sufficiently subtle, you’ll twist an explanation into justification for your wrong idea. The research on that is Newton’s Third Law. I think .NET overload oddities may be similarly subtle…

Using the Puzzles

It’s incredibly hard in the midst of the video to avoid sounding condescending when I say “write down your answer or play with Visual Studio.” But there is no other way in the format video for you to show yourself that you are wrong, or right. I’m not going to slap you, and I don’t know if anyone is clever enough to make you laugh at .NET overloads subtleties. Black and white “OMG, I was wrong! About that?! I was wrong!” is enough. When you see you are wrong, the neurons just can’t route what you’re hearing to support your previous notion. You push away the bush and see that it really isn’t a tiger’s eye.

You have a special propensity to learn from itty bitty trauma, fear and surprise. I can’t count the number of times someone said “I know that, but only because…” and they can tell me with excruciating detail exactly how it screwed up a project… their little trauma…

Puzzles create little itty bitty no-overhead, no liability, no risk trauma. Watch a puzzle question clip stop the video and think. Doodle. Write. Propose. Experiment. Drive to work. Do something kinesthetic – at least move a pencil in the shape of your answer or guess.

If you’re right, the affirmation will be a little stronger. If you’re wrong, the likelihood you’ll remember will be significantly higher. And that’s the purpose of these puzzles.

But, there is something wrong with the plus operand puzzle…

Why didn’t the plus operand puzzle in the previous blog post make it into the course?

It’s a nice example to talk about, but the chances of that really hosing you seems small to me. Sure, you could have a typo in a report from it, and you might get some weird data into a string in your database. And if you’re creating a niche app like data collection from streams it might be bad. But, I think that any competent programmer seeing an integer and a string is going to fix it, at least by clarifying with an explicit “.ToString()”

There are two bars for the puzzles in the course –both just my subjective view.

- Are there enough programmers that would get it wrong to be interesting?

- Is there a fair chance that getting it wrong could cause a significant problem?

This puzzle passes the first bar, but just barely misses the second. It’s more than trivia, but not quite significant enough to seem like more than a low value puzzle.

Seriously, stop the video

A lot of you think you had the right answer and didn’t. You aren’t dishonest, you aren’t cheating, it’s just the human brain is wired. It wasn’t a tiger’s eye, and you moved on.

One way to break these patterns is to stop the video, think, record, and then see the result by watching the answer clip. Another is to encounter the problem in your own code an spend a traumatic day debugging.

And if you’re really interested in upping your game, do what James did. After you watch the answer clip, stop the video again. Ask yourself about the implications to your own code. Ask yourself about implications beyond what I covered – in the operand puzzle, I explicitly didn’t tell you what happens with a double, Boolean, decimal or .NET object. What about an enum?

And then, let me know

The puzzles video is an experiment. It’s a hard to video to record, and I don’t know whether to continue the format. I’ve got lots of puzzle ideas, help me decide whether to do more courses using this format.

Summary of ETW Support in .NET

Wow, what a year for tracing, what a month, what a week!

If you’re in the midst of what’s happening in tracing, your head is spinning with how much the teams have accomplished. If you aren’t in the midst of it, I suspect you’re either unaware or you feel lost.

Trust me, in the midst of the decade of change in tracing, this last week was the tipping point. In the last seven days, we’ve seen the release of Microsoft.Diagnostics.EventSource, Microsoft.Diagnostics.TraceEvent and the WPR/WPA announcement for Windows 8.1.

There’s a lot of work still to accomplish for a truly mature diagnostics story. But going forward I think the big questions are guidelines for EventSource style tracing, what consumers should look like for specific tasks, and alleviating pain points. This week the supporting tools became adequate.

It is nearly impossible to keep straight what component is contributing which key piece of the puzzle. In this post, I’ll summarize and provide what I think are the most important links. If I make a mistake, comment please and I’ll update. If I left out one of your favorite links, please add it in the comments.

At the end of the post, I’ll describe channels and manifests becaues I can’t find concise descriptions.

System.Diagnostics (except System.Diagnostics.Tracing)

· All usage of Trace and TraceSource classes should be reevaluated going forward

Event Tracing for Windows (ETW) (info here and here)

· Very fast, common, tracing subsystem

· Strongly typed events

· Component model with interface driven controllers, providers and consumers

· By implication independent core (Silverlight potential)

System.Diagnostics.Tracing.EventSource (.NET 4.5) (info here)

· Easy placement of your trace events into the ETW debug channel independent of System.Diagnostics overhead

· Strongly typed events available in .NET

· In-line manifests

· In-proc EventSource collection (not the common case)

Semantic Logging Application Block (SLAB) (info here and here)

· Alternate output to ETW allowing a natural logging experience during development that morphs to production ETW tracing via configuration (debug channel)

· Tools to test correctness of EventSource classes

Microsoft.Diagnostics.EventSource (info here)

· Adds EventSource support for alternate channels: including admin channel support which means the ability to write to the Event Log with strongly typed events

· Provides EventSource support in .NET 4.0

· Installed manifest support for EventSource (manifest creation and installer created as build step): allows manifest installation for Event Viewer support

· Build time validation of EventSource classes

WPA/WPR Support (info here)

· Contained in the Windows Assessment and Deployment Kit (Windows ADK) for Windows 8.1 Preview

· Support for in-line manifests in mainstream tools as controllers and consumers

Microsoft.Diagnostics.TraceEvent (info here)

· Out of proc (the common case) ETW support from within .NET

· Library to create ETW events (including EventSource/in-line manifests) controllers (start/stop)

· Library to ETW events (including EventSource/in-line manifests) consumers (filter, load, evaluate, display)

· While you may not use this directly, it’s a critical step in providing better tools, particularly for consuming ETW

A Few Definitions

If you’re not familiar with ETW, the discussion above may require a few definitions.

Channel

ETW supports four channels as the highest level of filtering breakdown according to target audience. The definitions from here:

Admin type channels support events that target end users, administrators, and support personnel. Events written to the Admin channels should have a well-defined solution on which the administrator can act. An example of an admin event is an event that occurs when an application fails to connect to a printer. These events are either well-documented or have a message associated with them that gives the reader direct instructions of what must be done to rectify the problem.

Operational type channels support events that are used for analyzing and diagnosing a problem or occurrence. They can be used to trigger tools or tasks based on the problem or occurrence. An example of an operational event is an event that occurs when a printer is added or removed from a system.

Analytic type channels support events that are published in high volume. They describe program operation and indicate problems that cannot be handled by user intervention.

Debug type channels support events that are used solely by developers to diagnose a problem for debugging.

The admin and diagnostics channels appear to be the most common. The debug channel is sometimes called the diagnostic channel.

Manifest

To fulfill the goal of superfast tracing, ETW produces a binary stream containing a limited amount of human in-decipherable data. Strongly typed events cannot be used without a definition of the contents. This definition is contained in a manifest.

Historically this manifest was created as an XML document and installed onto the computer containing the ETW consumer. This model presented a host of issues, including being brittle, difficulties when multiple manifest versions existed on different production machines, and requiring complex installation. Some tools, including Event Viewer, support only installed manifests.

EventSource introduced in-line manifests. The manifest is simply another event in the ETW stream and is installed in memory only when it appears. This is a much more flexible model and will be important going forward.

New Puzzle!

This post contains a puzzle I want to share that doesn’t appear in my .NET Puzzles, Gotchas and Cautionary Tales course.

[TestMethod]

//[ExpectedException(typeof(Exception),AllowDerivedTypes=true)]

public void TestMethod1()

{

    //Assert.AreEqual("42", "" + 4 + 2);

    //Assert.AreEqual(6, "" + 4 + 2);

 

    var four = 4;

    var two = "2";

    //var y = four + two;

    //Assert.AreEqual("42", y);

    //Assert.AreEqual("6", y);

 

    string x = (4 + 2).ToString();

    //Assert.AreEqual("42", x);

    //Assert.AreEqual("6", x);

}

If you see this code, you’re likely to have a gut reaction of “that’s wonky and I’d fix it”. I would too. I’m not suggestion you deliberately write code like this. But if you run across this code, you should know what’s going to happen.

Before you read on, predict what will happen in each of the three scenarios. If you uncomment one of the first two lines, will the code compile? If it compiles, will it run? If it runs, what’s the result? Do the same for all three sets. What’s the result? Like a goal, a prediction isn’t really a prediction unless you write it down. Or better, copy the code into a VS unit test project and start uncommenting things to see what happens.

And it’s relatively irrelevant what you think should happen. Reality is well, real.

In the course, I often start with an explanation of why this might appear and why it might be obscured with odd parameter names like a string property or parameter named “number”. I follow that with the simplest, most obvious, example I can think of, like the one above.

I suggest you pause the video and think about it. A little spinny ball is intended to remind you to think. If the ball reminds you of a song, let me know what song J

Then go on to the answer clip. It’s introduced with a different spinny ball to let you know time’s almost up. The answer clip shows you what works, and varying amounts of background material. There are also bonus clips with more background material.

I’ve rattling on in this blog post to simulate pausing the video by, hopefully covering up the answer while you think about the question.  Maybe I got a bit carried away, so here’s the answer:

[TestMethod]

//[ExpectedException(typeof(Exception),AllowDerivedTypes=true)]

public void TestMethod1()

{

    Assert.AreEqual("42", "" + 4 + 2);

    //Assert.AreEqual(6, "" + 4 + 2);

 

    var four = 4;

    var two = "2";

    var y = four + two;

    Assert.AreEqual("42", y);

    //Assert.AreEqual("6", y);

 

    string x = (4 + 2).ToString();

    //Assert.AreEqual("42", x);

    Assert.AreEqual("6", x);

}

 

The reason for the basic behavior is simple. C# puts an implicit .ToString() onto the integers to make the type work.

You can compile the second assert without error because one of the overloads for AreEqual takes two objects. Obviously, that test would fail.

What I really want is for you to think beyond the puzzle. In this case, if you looked at the first assert and thought “hmm, I wonder if it mattered that the first operand was a string. What would happen with 4 + 2 + "" For that, I’ll let you open up Visual Studio and check it out, it might not be what you expect.

.NET Puzzles, Gotchas and Cautionary Tales

My new Pluralsight video – .NET Puzzles, Gotchas and Cautionary Tales is here.

What do I know from over ten years teaching .NET?

I know you’re smart, I know you’re busy, and I know you sometimes feel overwhelmed.

What do I know about the nature of .NET?

It’s big. Really big. .NET, Visual Studio, and the surrounding landscape change crazy fast!

What do I know about the arc, the history of .NET?

It’s more than a dozen year’s old. There are programmers that weren’t born at its release and senior programmers that never worked without generics.

Why this course?

I’ve observed that almost everyone has holes in their .NET knowledge (OK, in my experience it’s everyone, but I know the world is a big place). They either never heard or forgot key points about .NET.

This isn’t trivia, many of the puzzles in the course are about program flow. Others are about the outcome of calculations. A couple are about potentially massive performance issues.

You’re successful at your job because you get these things right almost all the time – you understand most of the .NET framework. Or you have an effective mythos (Drew the Guru said…). But sometimes you get it wrong. You spend a day chasing a bug that was a framework misunderstanding or you put code in place that will cause problems later.

This course is about upping your game, making you more robust.

Why Puzzles?

Putting an issue out in the form of code and asking “What will happen here?” let’s you interact with the puzzles in the same manner you’ll interact with the problem in your own code. Well, almost the same. I was doing a puzzles seminar once, and a very smart programmer expressed the sentiment of his user group “it has to be x, but if it were x, you wouldn’t be asking whether x.” I also simplify the code to spotlight single issues – these will always be more subtle when they pop up in your own code.

To get the most from this course, think about the questions. The course is a plate of food, not an IV drip. Up to a point, the more you think, the more you’ll learn. Stop the video, get out your knife and fork, or pencil and Visual Studio, and mentally chew up the questions before jumping on to the answer video.

It’s not a beginner’s course. If you’re new, I’d suggest watching courses like Scott Allen’s C# Fundamentals courses first. But whether you’ve just got a toe hold in the basics, or you’ve been in .NET since the early betas – there’s something here to surprise you!

Why bonus clips?

Where the material was long and didn’t fit the puzzle format, I used a bonus clip. Maybe you already know that Contains() is faster than Any() which is faster than Where() when you’re just checking existence. Maybe it doesn’t matter because you aren’t using an enormous collection. That kind of stuff is in a bonus clip.

Working together

Now, if you really want to learn a lot from this course, watch it with a buddy. “I think because…” and “wow, that isn’t consistent with…” and even better “how does this affect this aspect of our app…” fundamentally change how your brain processes and make retention more likely. It’s a great course for a study group. Plan time to explore – “well, if that is true, what would happen if…“

No judgment and no scores. Programmers you really respect have gotten these wrong. Have fun!

Feedback

I’ve really enjoyed using this format in User Groups and I use puzzles in workshops to set the stage for deeper dives into .NET. I’ve talked about some of these puzzles for years, but I’ve never put together a video. I’d really like to hear how the puzzle format works for you, and of course I’m always happy to hear about your favorite .NET quirk.