Nullable references in C#

Tim B went to see Jon Skeet at the recent Oxford .NET talk. Jon Skeet is the most prolific and highly voted Stack Overflow contributor ever. He was talking about the plans for C# 8.

Jon Skeet mostly talked about nullable reference types – what will happen, and his opinions about them. C# has value types and reference types, similarly to Java. C# currently has nullable value types – so you can have int? to represent a nullable integer. In C# 8, there will be “nullable reference types”. This seems a little odd, since reference types are already nullable – but it is to change the default behaviour of reference types so the compiler will warn if null is assigned to a reference type. This is only a language level change, not a CLR change.

The compiler will attempt to identify when a nullable object is referenced – and it tries to do this cleverly, by checking for things like “xx != null” that mean that a null reference might be accessed.

There are other changes coming around pattern matching in switch statements – similar to the way that this works in Scala.

We discussed the way that the C# language is evolving compared to the way that Java is evolving. We agreed that the C# language maintainers were much more willing to make significant language changes, whereas Java has been much more focussed on backwards compatibility and a much slower evolution.

Following this, we discussed Kubernetes, and our experience with it.

Testing Test Driven Development

In our dev meeting, we discussed Test Driven Development. So, of course, we did it TDD-style: we started off by asking whether everyone knew what TDD is; and then testing that; and then asking more questions about TDD until we got a failing test – i.e. several people who didn’t know. Then we updated our knowledge of TDD until we didn’t have a failing test, and iterated…

We agreed that there are many benefits to using TDD, of which “ending up with a working test suite” is only the most obvious:

  • Allows incremental development, so you are able to run the code as you’re going along
  • Provides documentation for how the code works
  • Helps you to get a feel for how the code will work as you’re writing the test
  • Proves safety, confidence, and a greater ability to refactor
  • Writing a test beforehand means that you are forced to have a failing test
  • Forces a different mindset – because you’re thinking about your design and API as you write
  • Helps you concentrate on what’s relevant to the task at hand, rather than doing unnecessary work
  • Encapsulates features nicely – encourages better organization
  • Helps keep focussed on the problem, and keeping the solution simple, rather than solving unimportant problems

But, we concluded that while many of us used TDD for some of the time, it wasn’t true that all of us were using TDD for all of the time. So, given all these great things about TDD, why aren’t we using TDD for everything?

  • We’re lazy
  • It takes longer to get to a result – longer term benefits but a short term cost
  • Not as good if you’re exploring
  • Some types of test are hard to write
  • Slow feedback loop for some types of test – e.g. some integration tests
  • Limited framework support
  • Working in an existing codebase that has been developed without TDD
  • Working with frameworks that have been written without testing in mind – particularly older frameworks
  • Working in very data-heavy projects, based on mutable source data
  • TDD is a bit less useful when the language is more focussed on the problem domain (e.g. C#) rather than more focussed on technical issues (like C++)

We discussed the level that we were “pure” in our application of TDD – whether we were always using a strict, Kent Beck approved “write the most minimal test, write a dumb implementation that just passes that test, then add more tests and refactor”. We concluded that we mostly weren’t – the range of TDD-like approaches that we use are:

  • Pure
  • Use a hybrid approach – write some minimal tests, write a real implementation, and extend the tests to cover edge cases
  • Write TDD-style¬† when it will actively speed up implementing a feature due to better turnaround time
  • Write out the specs first, and then implement the code based on that –
  • Write tests to help the code reviewer understand what’s been written: sometimes before writing the code, and sometimes after

We discussed a potential pitfall we had sometimes hit with TDD – that sometimes it is tempting to keep hammering at the code until the tests pass, rather than to step back from it to reconsider the overall strategy.

In conclusion – we use TDD a lot of the time, but we tend to use hybrid approaches rather than a strict pure approach.

Nothing to fear except hackfear itself

Nikolay talked about the #HACKFEAR hackathon  that he had recently been to. It was organized by Karen Palmer, a film maker and parkour practitioner. She is interested in fear РParkour is at its essence about fear management. She discussed a future in which technology has gone bad Рfor example, if you wanted by the police and you get into an automated car, it will take you straight to the police station and instead wants to use technology to help guide and empower people.

She has an art piece called “Riot” – which is a webcam watching you, while watching a video, and attempting to identify the emotion that you’re portraying using a neural network. If you show “appropriate” responses for the situation, then the video progresses; if you show inappropriate responses, then the video ends and you have as many attempts as you need.

At the hack, most of the hacking was about concepts, rather than fully working products. Nikolay’s group looked at fear of public speaking; taking the technology from Riot to analyze your posture and speech (e.g. how much you say ‘um’) to help provide feedback on your speaking.

Another team used a VR system to analyze your emotions and show you “scary” things, as exposure therapy to them. other teams that tackledmanagement of memory loss, fear of self expression as well as fear management through journals or improvenent of communication for early school-leavers.

We also discussed other types of fear, such as writers’ block, and acrophobia; and the difference between climbing a ladder, versus jumping off a cliff with a paragliding harness attached. While the latter should be scarier, it’s not, because you know that you have a harness.

Karen Palmer has TED talks about this topic.

Managing state with VueX

Tim talked about Flux, Redux and VueX, for managing state in JavaScript applications.

The big change between Flux and Redux was that in Flux there was one store per feature; in Redux the entire application state is stored in one central object. This makes it easy to serialize and debug. Changes to the store are made via a “reducer” – which is a function that takes the current state, and transforms it into a new state – similar to the way that state is managed in Elm. To help organize the state, then you can break it down into a set of smaller views of that state. Because you’re abstracting all the data into one place, then the components themselves can be simpler and dumber. This makes the components themselves easier to test.

VueX is a reimplementation of Redux, but focussed on Vue. While you can use Redux with Vue, it makes more sense to use VueX since it integrates better with Vue’s properties and events. The VueX dev tools have built in support for VueX, and they list the actions that are triggered at any point, showing when the state changes, and allowing you to step back before that. Also, there are libraries to serialize your entire state to local storage whenever there is a change, which makes it harder to lose state if you close your browser.

We discussed exactly what “state” means, and how much you want to have stored in the VueX state. It comes down to what is useful to you – you don’t necessarily need to store everything, just the things you care about.

Rich talked about a current project that’s using VueX; with a wizard that collects data from the client across multiple pages. This uses VueX to manage state.

We discussed when VueX was worth using. It adds flexibility, but it also adds complexity and means that you are distributing the code to manage state to more places. The recommendation from the Gitlab blog is to use VueX always. Tim doesn’t completely agree – it does add some extra boilerplate, but on the other hand it’s good discipline to make what your application does clearer. He’d use VueX for a new single page app, perhaps whatever the side. Rich on the other hand thought that it was more important to consider whether there is state on the client side that needs to be remembered between pages – so the wizard app needs that, but an app where the state is always synchronized with the server doesn’t need it.

Rich also mentioned a prefetch option in Vue Router, which can potentially make apps using the router perform more quickly.

Release It!

This week, in our dev meeting, Chris talked about Release It! (second edition) by Michael Nygard. He’d read the original years ago, before “dev-ops” existed, and it was the first time he’d really thought about putting applications into production. It was an eye-opener 10 years ago, so he was excited by the second edition.

The book discusses stability patterns and antipatterns; then about things to consider in production; then about deployment; then about evolution of applications. So far, Chris has only read the first two parts of the book.

It discusses “Designing for Production” rather than “Designing for QA”; starting with a case study about how a small problem escalated into a huge problem. Some approaches are:

  • “Testing for Longevity” – identifying things that will fail after X continuous days running, which might not be picked up by standard CI approaches
  • limiting chain reactions between servers if there’s a failure causing domino effects (often by blocked threads building up)
  • self-denial attacks like sending out mass emails that trigger everyone to look at your site simultaneously
  • dog-piling, which is a bit like the thundering herd problem, e.g. if everything server is updated on a schedule exactly on the hour it causes peaks in load
  • automated tools going out of control, so applying limits to them is good;

Positive approaches to avoid these are:

  • timeouts
  • circuit breakers – isolate your system from the remote system when the remote system is down, providing an immediate “fail” response rather than blocking and running out of threads
  • bulkheads – e.g. reserving a few threads for the admin tool to fix the problems, or the operating system saving some disk space so the root user can fix out-of-space problems
  • steady state – e.g. log files shouldn’t become infinite in size, they should be tidied up; temporary files should be deleted
  • fail fast – do validation as soon as possible, if there are expensive operations that require data, then get that data upfront
  • for websites, distinguish between 40x errors and 50x errors – a user entering bad data shouldn’t trigger a circuit breaker
  • let it crash – if something goes wrong, let it crash and then restart it, but this requires other architectural choices like supervisors
  • handshaking – typical REST services don’t have any handshake involved; sometimes it would be useful if they could return an HTTP 503 to their caller to tell it to slow down
  • asynch approaches – a pull system can choose the rate at which it receives content
  • shedding load – dropping load if it can’t take any more
  • back pressure – telling your caller “back off, I can’t take any more work”
  • governor – applying limits to the automation tool, so it can’t fire up 10,000 boxes immediately – if it’s outside the standard range of what it does, then it will do it more slowly

When building a system using an Agile approach, then you need to decide when to start applying these techniques – since they may not be expressed directly in user stories, and they may require significant architectural choices that are hard to refactor into an existing application. We discussed that some of these patterns are directly supported in newer frameworks, such as Akka HTTP; which has direct support for back pressure, circuit breakers and asynch methods. This makes the decision about when to implement them easier.

Dev meeting – Data intensive applications; and Rust

At our dev meeting this week, Rich talked about ‘Designing Data Intensive Applications‘, that he’d been reading, and Inigo talked about ‘Talking to your TV using Rust‘.

‘Designing Data Intensive Applications’, from O’Reilly, describes various tools and approaches for storing and processing data. It’s split into four sections. Section 1 discusses the basics of databases and how they store content, for SQL databases, NoSQL databases, flat file stores. It covers in-memory stands, b-trees, indexing structures, and the best approaches to use in various situations. Section 2 talks about distributed databases – clustering, transactions, serializing commits at a point in time so shared logs can work, and so on. Section 3 discusses distributed batch processing, using tools like Spark. The first three sections were all very interesting and informative. The fourth section was not as good – it covered the future of data, and was a lot woollier than the previous sections. Rich found the book on the whole good.

To talk to his TV using Rust, Inigo used a Google Home Mini, an RM 3 Mini IR blaster, an Open Source library to interface with the IR blaster, and some Rust on a Raspberry Pi. The Google Home part was setting up a Google Home App via https://developers.google.com/actions/building-your-apps – you configure a set of actions and intents online, and then assign a ‘fulfillment’ to it, which is a web service you make available via HTTPS. This part is fairly straightforwards – it requires filling in various web forms, and it’s easy to publish a test version of an app that’s only available via your own Google account.

To actually use this for a home application, you need to have SSL, so you need a domain name and a certificate. Inigo used Amazon Route 53 for the domain name, and Lets Encrypt for the certificate. There are various other services that will provide a domain name for a dynamic IP address for free, although the original dyndns is no longer free.

THe ‘fulfillment’ part is a web service that Inigo wrote that accepts JSON from Google, and then calls out to a Python library that interacts with the IR blaster. He wrote the first version in Scala, to get something simple working fast, and then rewrote it in Rust. He learned from O’Reilly’s Programming Rust book, and used IDEA’s Rust plugin. The experience was positive, although it was a bit tricky to get some of the memory management working correctly as a first-timer using Rust. The code is on Github at https://github.com/inigo/googlehome-remotecontrol.

How to read more interesting books

In our dev meeting, we talked about interesting development related books we had read, and how to read more interesting books. Various people each talked about a book that they had read recently or recommended.

Chris talked about “The Nature of Software Development“, by Ron Jeffries.

It’s by Ron Jeffries, one of the signers of the Agile Manifesto signer. It’s a good book to give to people who don’t know about Agile, and who might be scared of Agile jargon – it’s entirely jargon free. It explains the fundamentals, and the reasons why software development is better done Agile. It cuts through the cargo culting that is common with Agile implementations.

Tim talked about “What to look for in a code review“, by Trisha Gee.

The author is from Jetbrains, and there is a little undercover marketing for Jetbrains tools, but it’s not excessive. It’s written pragmatically (although not from the Pragmatic Press!). It’s very short, which is a plus, particularly if you have a young child and limited reading time. It is split into chapters based on things to look for in code reviews, like tests, security, performance, good principles. Although it is fairly Java focussed, it is still useful for any language. The tips are fairly obvious to most experienced developers, but there is some good stuff in there.

Pasquale talked about “Clean Coder” by Bob Martin.

This is about “saying no” and “saying yes” – the language used when committing to a task – you should say what you’re going to do and then do it. It recommends and explains Test Driven Development. It recommends coding practice, using katas. It discusses time management and managing your own time; and doing estimation. It is good for intermediate developers.

Loic talked about “Designing the user interface“.

This is a classic of Human-Computer Interaction. It’s primarily aimed at students. It covers a little of everything you need to know about HCI; usability, mice, collaboration, etc. It is useful for all developers to learn a bit about usability. It’s 20 years old, and a bit dated – but still relevant.

Reece talked about “The Design and Evaluation of C++“.

This book describes how the early C++ compiler was created, and how various features were designed, and the compromises made to overcome problems. It goes up to C++ 98. It is good for anyone interested in the history of programming languages and how they are created and evolve.

Simon talked about “My job went to India” (now renamed to “The Passionate Programmer“).

Simon read this about 10 years ago, and still recommends it. It is organized into 6 sections, with 52 tips across that. It is useful to think about how to do more than just what’s needed right now in the short-term. Some particular tips are: “Be a generalist” – don’t get bogged down in particular technologies; “Be the worst” – have better people around you; “Be a mind reader” – think about the software being developed and spike out future requirements that haven’t yet been considered, and think about what a customer might need, but they aren’t saying; “Be where you’re at” – do your job well; “How much are you worth” – was the work I did today worth what I am paid? The book could be read by anyone working in tech, but it’s aimed more at programming than other tech jobs. The ‘outsourcing’ part of the title is just a marketing vehicle.

Stephen talked about the “Mythical Man Month

It was written in 1975, but is still true, although a bit dated. Its core message is that a job that takes two months for two people, does not take one month for four people – because of communication, training, etc. It famously coined “Brooks’ Law” – adding more people to a late project makes it later. That’s still true, although perhaps less so nowadays since people it’s easier to split up tasks and make them independent. Sometimes you think “I could have done that in an hour” – but it actually takes a day: because it takes nine times longer to write good quality deployable shareable code, than it does to write something for yourself only. A modern insight on this is that reuse of code, better tools, and TDD can all help.

We had technology problems talking to Bart, but he passed on his notes on “Algorithms To Live By“.

  • It is a book on algorithms that either technical and non-technical people can get an insight on most important algorithms in computer science. Algorithms are presented in form of brief history and application in daily life. For people with computing background this could be a great supplement to already gained knowledge , i.e in the university. For non-computing people this would explain that computer science is not only about installing/fixing Windows. Some of the chapters most interesting to Bart are:
  • Optimal stopping – you will learn the most efficient methods to employ secretary, find a wife or parking space, or sell the house
  • Explore and exploit – you will learn how medical trials with unknown drugs are conducted, when to stop looking for a good restaurant, how the founder of Amazon explains Regret Optimism
  • Caching: How to store data, clean up the house, and human memory issues
  • Scheduling – importance of time, various methods to resolve problem with tasks dependency, how Pathfinder stop responding and was fixed while on Mars
  • Overfitting: how not to over-learn (self and machines)
  • Randomness – how to calculate PI by dropping a pin, how playing cards helped in building the atomic bomb, how to find gigantic prime numbers
  • Games theory – recursion in humans decisions, the “Prisoners’ dilemma” explained

Rhys also wasn’t present, but passed on his recommendation for “Functional Programming in Scala

This discusses how to solve problems in a functional way, how to think about combining functions in algebraic way. It includes exercises too. Particularly when coming from a Java / procedural background, it’s quite a mind shift.

We also briefly discussed why those particular books:

  • Chris had seen it on PragProg.com, and read about it on the mailing list, and liked Ron Jeffries as an author.
  • Tim has a young child and wanted to read a short book.
  • Pasquale realized that human processes around coding are important, and had already read and liked Clean Code.
  • Loic studied HCI at university, and it’s a heavily recommended book from ACM curriculum.
  • Reece is interested in language design, and this was written by the creator of C++. It was interesting to see thought processes of language designers.
  • Simon was doing a lot of Ruby development at the time, and reading blog posts by the author of the book, and found his attitude of interest – and the book was unexpectedly good.
  • Stephen read Mythical Man Month because it was famous.

 

Dev meeting – Effective Java (again)

Stephen recently read Effective Java, by Josh Bloch, and we discussed things that he picked up from it, particularly approaching Java from a perspective of much more experience in C# than in Java.

  • When you have multiple overloaded constructors, instead use a static factory method on the class. We discussed the advantages and disadvantages of this.
  • We discussed the preference for interfaces rather than concrete classes in Java vs C#. We discussed how this was probably influenced by type inference and type erasure. It may also be related to Java’s history with frameworks like Hibernate and Spring, that initially used lots of interfaces to support proxies before bytecode rewriting became common.
  • Overriding equals and hashcode – it’s common in Java, but less common in C#. In Scala, case classes remove a lot of this complexity. We discussed what identity means for classes and objects, and how you express that in various languages.
  • The difference between Exceptions and RuntimeExceptions is surprising from a C# background. We discussed the merits of checked exceptions – we broadly agreed that in an ideal world, checked exceptions were a good idea, but in practice it depends on library authors being competent and library users being competent. Sadly, this doesn’t happen. Checked exceptions also cause issues for lambda functions. There was some discussion that the way Scala does this is better.
  • The use of external libraries – it’s a lot more common in Java, whereas .NET developers tend to use the CLR content much more frequently. We discussed the issues of transitive dependencies in Java bulking out your build. We also discussed how the ‘small number of large libraries’ assumption is no longer true in .NET Core – there are many different packages within .NET Core.

We discussed Effective Java a while ago in a previous dev meeting, too.

 

Dev meeting – AIs, interplanetary file systems and Nix

We had several lighting talks in the dev meeting this week.

Rich talked about WitAI – a language parsing web service that helps with building chatbots. He’s written a “drinksbot” in it, which we used via Slack before the dev meeting to order drinks. You provide it with a corpus of example sentences, and it learns from that.

Chris spoke on the Interplanetary file system. In typical direct file request, you might retrieve it synchronously from a single location. IPFS allows you to retrieve content from a set of distributed stores – essentially a peer-to-peer, torrent-like filesystem, that can be more robust and potentially faster than a direct file retrieval; because content is stored can be stored in a number of places.

Reece talked about antagonistic attacks on neural networks. Because neural networks (e.g. for image recognition) will typically work by perturb the input image to make the neural network recognize it as something entirely different – even though the change to the human might be imperceptible. For example – researchers recently made a model of a turtle (to human eyes) look like a gun (to neural network recognition) to illustrate this issue. This is a problem with neural networks generally – that the neural network may be using very specific things for its recognition, and it may be hard to identify these.

Stephen talked about teaching (very) young developers – like his daughter – to program. There is a lot of implicit knowledge and setup and background in a typical dev environment, and you want to get to working code as quickly as possible. HTML 5 and JavaScript are good for this. You should optimize for small victories, and concentrate on fast feedback loops.

Tim talked about Vue, the JS framework. You create reusable components that have an HTML component and some connected JavaScript that can control . It’s somewhere in the middle in terms of ease of use – it’s more complicated and powerful than Knockout, but simpler and more usable than React and Angular (and it can be used initially just by including script tags, and then extended to manage things like transpilation). We’re using it in a number of projects at present.

Rodney talked about “Where I’ve been” – specifically about the Nix conference that he recently attended. There is a new Nix tool for handling packaging and building in the Nix system, which has a simpler (command-line) UI. Another talk was about the security developments to the Nix project, such as having specific security experts who can getting security notifications from other projects early on; about automated scanning tools for scanning deployed Nix implementations for security holes. Nix in production was being discussed – e.g. for a company that’s doing cycle dock management in the Netherlands. Using Nix throughout an entire environment, from development through to production, brings many advantages. At Tumblr, Nix is used for testing of live SQL instance replication. Then there was a Hackfest – with spontaneous collaboration, and good work done on Nix cross-compilation.

Tell me more about talking about chatbots

In our dev meeting this week, Alex talked about chatbots. Bots are a massive shift in how we interact with computers – but to some extent they’re still a solution looking for a problem. Bots are conversation driven – and developers typically have never dealt with conversation! There’s a lot of existing support for English language bots that comprehend language reasonably – but there’s far less support for non-English bots. There are libraries and services to help with this – for example, Microsoft Cognitive Services provides endpoints that pick out from the users input what the user is asking, and even what their emotions are. However, these tools are probabilistic – they will say “it’s 90% likely that the user wants this”, rather than “the user definitely wants this”. Bots can get confused – because the bot will typically maintain state so it can refer back to earlier elements of the conversation, it may sometimes lose track of where it is – and needs to be reset. However – this is adding complexity to what is supposedly an intuitive interface; and users may not understand the underlying complexity.

You need to think about the platform that you’re deploying to, in terms of how you develop your bot and what capabilities you expect it to have. Slack bots, bots responding to SMS, Facebook bots – all have different characteristics based on the capabilities of the platform they’re running against. This also shapes what users expect in terms of level of communication – no-one expects lengthy complex sentences from an SMS bot, but they might do from a Slack bot. Discord bots have an expectation that they’re used for gaming, because of the assumptions of the Discord culture. Facebook bots have more in the way of graphics and buttons – so they’re moving to “Monkey Island” style user interfaces, whereas other bots are more similar to an old-style text adventure user interface or a Twine (and Twine is good for developing bots).

For bots, uptime is critical – so the bot should always be available. However, it’s not essential that they respond immediately at machine speeds – in some ways its better to pause a few seconds, because it may feel more natural, as well as helping deal with load. Cloud hosting is useful for bot development to help with this availability and coping with load. Also tracking user responses is important.

Given these complexities – why bots? It offers a high engagement rate, because it’s the same way of communicating as people are used to using with their friends. Bots can be proactive – if a user looks up an event like a concert, then the bot can prompt that the user might want to buy a ticket for it. Bots can be more engaging for users who are unfamiliar with technology. Bots are new and exciting – it’s immature and in flux, and there are no great settled ways of doing things, so it’s good for experimentation. There’s lots of space for exploration – like creating a Twitter bot that offers to sell wine to people based on their tweets of wine bottles. They are a new space – and we should think about ‘how can a bot benefit you’ – like using a bot to collect orders to buy drinks at the bar. Go forth, and make the next Flappy Bird of bots!