Last updated: August 17, 2017 08:22 PM (All times are UTC.)

August 17, 2017

The cure for Apple is not cost-cutting; the cure for Apple is to innovate its way out of its current predicament”. Steve Jobs When Steve Jobs returned to Apple after over a decade away from the company, he prioritised innovation as the driving force with the potential to transform the brand. He was right. From being […]

The post Why we dedicate 10% to R&D appeared first on stickee - technology that sticks.

August 15, 2017

A problem I was investigating today led me to a two-line Ruby method much like this:

class App
  # ...
  def write_file_if_configured
    file_writer =
    file_writer.write if file_writer.can_write?

This method definitely looks nice and object-oriented, and satisfies many code quality rules: it’s shorter than 10 lines, contains no branches, no Boolean parameters (unless there are any hiding in that options object?), indeed no parameters at all.

It also conforms to the Law of Demeter: it calls a method on one of its fields, it creates a local object and calls methods on that objects, and it doesn’t send messages to any other object.

In fact there’s significant Feature Envy in this method. The method is much more interested in the FileWriter than in its own class, only passing along some data. Moreover, it’s not merely using the writer, it’s creating it too.

That means that there’s no way that this method can take advantage of polymorphism. The behaviour, all invoked on the second line, can only be performed by an instance of FileWriter, the classglobal variable invoked on the first line.

FileWriter has no independent existence, and therefore is not really an object. It’s a procedure (one that uses @configuration.options to discover whether a file can be written, and write that file if so), that’s been split into three procedure calls that must be invoked in sequence. There’s no encapsulation, because nothing is hidden: creation and use are all right there in one place. The App class is not open to extension because the extension point (the choice of writer object) is tightly coupled to the behaviour.

Unsurprisingly that makes this code harder to “reason about” (a fancy phrase meaning “grok”) than it could otherwise be, and that with no additional benefit coming from encapsulation or polymorphism. Once again, the failure of object-oriented programming is discovered to be that it hasn’t been tried.

Santander Bank customers should be aware of an effective spam campaign spreading the Trickbot banking Trojan that is coming from domains similar to those used by the financial institution.

August 14, 2017

Cloud Security has been a serious issue since the concept of the cloud began. The classic example was initially the discomfort of a shift from physically seeing the IT security infrastructure to simply trusting someone else with it virtually. One way to ensure a full understanding of cloud security, and security in general, is to understand the levels of your infrastructure that require protection.

August 13, 2017

August 11, 2017

Reading List by Bruce Lawson (@brucel)

August 08, 2017

A cyber risk analyst at security firm UpGuard, found the data on July 6. Files included schematics that highlighted “potential weak points and trouble in customer electrical systems,” according to a report published Monday by UpGuard.
Cyber security is now a pressing issue for many organisations. If you're unaccustomed to the technology sector, it can be hard to decode the extensive volume of technical language. As part of the research project I am currently involved, cyber security concerns within UK businesses is a key area. Given the nature of this topic there is a wealth of language that I was initially unable to fully understand. Read more as I attempt to break down the complicated language surrounding the topic in a Glossary of terms and what they mean.

August 07, 2017

A common code smell that tends to go unnoticed is embedding a time span within a variable name. While developers recognize that embedding types into names is redundant they often fail to see this smell.

You often need a variable to trigger on a set period, such as every fifteen minutes. For example:

BlogPostFeedPollingIntervalInSeconds = 900

In this example, what is 900? Without the variable name this is hard to reason about. This is even harder when the value is external and replaced on deployment. Often the value will be found with a comment explaining what the figure is relative to other time periods. This is another hint that you have a time span embedded into a variable.

This smell also becomes harder for more exotic or unfamiliar intervals. In other words most developers are familiar that 1 second in milliseconds is 1000, but not other common ranges or periods. Most standard libraries or lower level functions have fixed intervals which compound the problem. For example a data access libraries tend to use seconds as their highest unit of time, this may not be appropriate in some cases.


The fix for this code smell is to use time spans. The previous example can be expressed in the following form.

BlogPostFeedPollingInterval = "00:15:00"

The value here is expressed in the form HH:MM:SS. Time spans can include days or levels of precision lower than a single second. Different languages may have alternative forms of specifying time spans but the principle is the same. Consult the documentation for more info. When the code reads this value the string time span will be converted. Using C# as an example:

var blogPostFeedPollingInterval = TimeSpan.Parse(timeSpan);

The use of time spans have a variety of benefits. Notice that the variable name has had the time component removed. This allows the value to increase or decrease without needing to change the variable name.

Additionally time spans are human readably without the need to convert or do maths in your head.

Time spans also offer type safety if the underlying code is doing further work with the value. This is in stark contrast to doing numerical work with simple integers. Another example would include the ability to use higher time periods for clarity and then simply convert to the total number of minutes/seconds when required.

It is worth bearing in mind that for time periods such as "12 months" or "every 3 weeks on Friday" an alternative is required. Some languages may offer this by default, others may require a third party library. This is due to the fact that a time span does not respect the calendar system. For example, over several months the number of days in each month can vary. For days, hours, minutes or seconds your standard libraries time span should be more than capable.


  • Don't embed time spans in variables.
  • Whenever you include a time span in a variable name consider using a time span.
  • Check the documentation for your language as time span formats can differ or be tricky to remember.
  • For periods of time (every 3 months on the 1st) time spans are not appropriate by default.
  • For business rules that must trigger on on particular dates as previously use the calendar to work this out.

August 04, 2017

After teaming up with IndieGala, our Virtual Reality game ‘Thunder Spheres’ is available to order as part of their online virtual games bundle. Available for a limited time only, the game is listed at a discounted price with two other games available in this fantastic offer. Over the past 12 months our R&D team have […]

The post Thunder Spheres available on IndieGala appeared first on stickee - technology that sticks.

Reading List by Bruce Lawson (@brucel)

August 03, 2017

Marcus Hutchins, the researcher hailed for his work in blunting the WannaCry ransomware outbreak in May, was arrested Wednesday in Las Vegas and charged with creating and distributing the Kronos banking malware.
Microsoft Azure is a cloud service from the global software giant, Microsoft. Azure offers a vast range of useful compute and application resources. These are all offered on-demand and in a cost-effective manner which helps businesses scale and grow. Hopefully, like me, you can learn from this glossary even complicated sounding terminology usually has a simple explanation. Which can be useful when developing your knowledge on technical topics.

August 01, 2017

Merck, among the world’s largest pharmaceutical companies, said in its quarterly earnings report last week that it has still not fully recovered from the June 27 attack.

July 31, 2017

I was reading about Clojure’s views on truth and falsehood this morning. Some of them are interesting:
(true? true) ; -> true
(false? false) ; -> true – a classic double negative

Clojure also has the value ‘nil’.
(true? nil) ; -> false
(false? nil) ; -> false

Then I went on LinkedIn and someone asked if there is ever an absolute truth. It’s a question I’ve been thinking about, so I wrote this:

I think that “at non-quantum scales”, it seems likely there can be only one set of events which actually happened but every human is wandering around in their own model of reality, based on their perception of incomplete data. Sometimes, a slow-motion replay helps fill in some of the gaps but it will be the same every time we look and it may not reveal ‘the whole truth’ we seek. We all have a simplified view of what reality is, based on our personal knowledge and beliefs and we can’t go back in time for more data, so our view of truth is an approximation. Heisenberg’s Uncertainty Principle says that it can only ever be an approximation.

In summary: I believe there is one truth but that doesn’t mean we will ever know what it is. Alternative perceptions may be just as valid as our own; possibly more so.

[ The original version of this post said nil meant “I don’t know.” I immediately discovered that was wrong. In Clojure, only ‘false’ returns ‘true’ to ‘false?’ but nil is ‘falsey’, so each of the following forms returns “F”:
(if false “T” “F”)
(if nil “T” “F”)
You can see how that could confuse a stupid person ]

July 29, 2017

I tried to address a question about data structure on Quora. This post is a stand-alone version of the answer I gave.

‘In the beginning’ there was ‘Data Processing’. That is: ‘data’ and ‘process’, expressed in the form of a program. Programs implement algorithms.

In 1976, the practice of ‘Structured Programming’ was trending and a book was written: Algorithms + Data Structures = Programs ( Wikipedia entry)

Processes and their structure + Data and it’s structure = Programs.

If you ignore interactions with the real world, that’s all there is. If you take any working program and ignore the processes and their structure and the raw data, then whatever is left is data structure.

We structure data because the alternative is data sauce, traditionally only ever served with spaghetti code.

July 28, 2017

Reading List by Bruce Lawson (@brucel)

July 27, 2017

A ransomware study released Google revealed the malware earned criminals $25 million over the past two years.

July 26, 2017

Two ways of thinking by Graham Lee

I’ve used this idea in conversations for years, and can’t find a post on it, which I find surprising but there you go. There are, broadly speaking, two different ways to look at programming languages. And I think that these mean two different ways to select programming languages, which are asymmetric. However, they can lead to the same choice, but viewed in different ways: if you use one of those languages then you need to understand that these different views exist to understand decisions made by programmers working in those languages.

On the one hand, the Language Lawyer seeks out languages with plenty of esoterica and specifics, in order to become proficient at recalling those esoterica and demonstrating their correct application. The Language Lawyer loves that reference and value types in swift are actually called class and struct, or that the difference between class and struct in C++ is the default member visibility, and that neither is actually related to the words class or struct. They are delighted both to know and to explain that in Perl 5, @var, \var and $var refer to the same variable but are accessed in different contexts and what they evaluate to in those contexts. They are excited to explain that technically the admonition that you must always return a value from a non-void function in C is not true, because since C99 if you have a function called main that returns control without returning a value, the compiler will implicitly return 0.

The Language Lawyer seeks out a language with such esoterica. But learning it is complex and time-consuming, so they probably don’t change particularly often. In fact, changing language may be deleterious, because then other people will know the esoterica that they get caught out on. Imagine knowing how the function overloading rules in C++ work, then trying something similar in Java and finding that you’re wrong. And that somebody else knows that. The shame! Once their language is chosen, the Language Lawyer will form heuristic rules of which language feature to use when solving which problem.

Standing in the other corner, the Lazy Evaluator wants to avoid those edge cases, because it makes them think about the programming language, not the software problem. They’d much prefer to have an environment in which there’s as much as one way to express their solution, then worry about how to express their solution using that one tool. The Lazy Evaluator loves Ruby because Everything Is An Object (and they love Io more because in Ruby there are also classes). The Lazy Evaluator is delighted to know that in Lisp, Everything Is A List. They are excited to be programming in Haskell, where Everything Is A Function.

Both of these people can be happy with the same programming language, though clearly this will be for different reasons, and their different thought processes will bring them into conflict. The Lazy Evaluator will be happy enough using the third-most common C-family language, C++– (full name: “C++98 but never use exceptions or templates, avoid multiple inheritance, and [never/always] mark methods as virtual”). The Language Lawyer will enjoy demonstrating const-correctness and the difference between l-, r-, pr-, gl- and x-values, but the two will come to blows over whether the Lazy Evaluator is denying the full elegant expressiveness of the language by proscribing exceptions.

Similarly, the Lazy Evaluator can look at JavaScript, see the simple classless object model with dynamic dispatch remembered from Self or Io, even notice that Functions Are Objects Too and work in that Everything Is An Object paradigm. The Language Lawyer can be confident that at some point, all of the weird coercion behaviour, the Which this Is That this Anyway question, and the You Need That Flag With This Polyfill To Get That Language Feature issues will come up. But the Lazy Evaluator will notice that That Flag also enables class syntax and arrow functions, we already have prototypes and function functions, and disagreement will ensue.

So in what way are those ways of thinking asymmetric? Invoking Hickey’s Corollary, you can never be recomplecting. It’s easier to compromise on C++ But Without Exceptions than it is to compromise on Lisp But We’ll Add Other Atom Types. You can choose JavaScript But Never Use this, you can’t choose Haskell But With Type-Escaping Side Effects.

This isn’t really about programming languages, it’s about any form of model or abstraction. Languages are a great example though. I think it’s a mindset thing. Your task is to solve this problem, using this tool. Are you focusing on the bit that’s about the problem, or the bit that’s about the tool? Both are needed.

Eulogy for Flash by Bruce Lawson (@brucel)

Yesterday, Adobe announced that Flash will be discontinued after 2020, news that was met with some rejoicing in the web development community, as confirmation that open standards “won”.

But the story is more nuanced than that. Glossing over the fact that Adobe didn’t invent Flash, the announcement is correct:

Where a format didn’t exist, we invented one – such as with Flash and Shockwave. And over time, as the web evolved, these new formats were adopted by the community, in some cases formed the basis for open standards, and became an essential part of the web.

There’s no doubt in my mind that Flash drove the web forward. It was eagerly adopted by many developers, partly because of excellent development tools, and because once deployed, it looked the same in all browsers and platforms (that Adobe released their plugin for).

In 2001, the W3C ended development of HTML on Xmas Eve 1999, and then gazed endlessly into its XHTML2 navel. Meanwhile browser vendors like Mozilla and Opera saw that Rich Internet Applications (like those Flash enabled) were part of the future of the Web, so WHATWG was founded to develop a spec called Web Applications 1.0 (later “HTML5”).

Browser vendors were scared of Flash (and Silverlight) with good reason. For example, when I set up glasshaus, a publishing imprint for web developers, colleagues in friends of ED (an imprint for Flash and Photoshop professionals) joked that there was no point, because browsers would be replaced by the Flash Player.

HTML5 was set up by browser vendors explicitly “in direct competition with other technologies intended for applications deployed over the Web, in particular Flash and Silverlight” and stole features directly from Flash: video, scriptable images (<canvas>), Web Sockets, in-browser storage, access to camera and microphone … the list goes on. Indeed, many of the early polyfills and fallbacks for these features used Flash. Apple invented CSS transitions and keyframe animations because they needed them on iOS, where they wouldn’t allow Flash to be.

And now Flash is reaching the end of its life. I’m glad, because now we have a more robust and future-proof open standard and open standards are always superior to proprietary ones. But I’m also nervous; one of the central tenets of HTML is to be backwards-compatible and not to break the web. It would be a huge loss if millions of Flash movies become unplayable. How can we preserve this part of our digital heritage? (Update 27 July: there’s a petition to open-source Flash Player to preserve content.)

As we open standards advocates pat ourselves on the back, it’s good manners to acknowledge the debt we owe to the Macromedia and Adobe engineers, and hundreds of thousands of Flash developers for pushing the web forward. Thank you.

July 25, 2017

July 22, 2017

Here’s an idea: the current backlash against OOP is actually because people aren’t doing OOP, they’re doing whatever they were doing before OOP. But they’re calling it OOP, because the people who were promoting OOP wanted them to believe that they were already doing OOP.

Why is that? Because the people who were promoting OOP wanted to sell their things. They were doing this in the 1980s to 1990s, when you could still expect developers to spend thousands of dollars on tools and libraries. “Here’s a thing that’s completely unlike what you’re already doing” is not as good a sales pitch as “ride the latest wave without boiling the ocean”. Object-Oriented principles were then hidden by the “Object Technology” companies – the StepStones, NeXTs, OTIs, OMGs – who wanted to make OOP accessible in order to sell their Object Technology.

That’s not the world of 2017. Nowadays, developer environments, libraries, deployment platforms etc are largely open source and free or very cheap, so rather than make an idea seem accessible, people try to make it seem important. We see that with the current wave (third wave? I’m not sure) of functional programming evangelism, where people are definitely trying to show that they are “functionaller than thou” rather than that you already know this stuff. Throw up a github or an npm that uses monad, pointfree or homoiconic without any indication of shame, and you’re functionalling right. Demonstrating that it’s already possible to curry methods in Objective-C is not the right way to functional.

If OOP were introduced into this world, you’d probably have a more dogmatic, “purer” representation of it than OOP as popularly practised today. You might even have OOP in Java.

One thing that makes me think that is that, well, it’s happened and it’s true. Multiple times. As previously explored here, protocol-oriented programming is just polymorphism under another name, and polymorphism will be found in a big-letters heading in any OOP book (in Barbara Liskov’s “Program Development in Java”, it’s chapter 8, “Polymorphic Abstractions”. In Bertrand Meyer’s “Touch of Class”, section 16.2, “Polymorphism”.

Similarly, what are microservices other than independent programs that maintain their own data and the operations on those data, performing those operations in response to receiving messages? What is a router at the front of a microservice but the message dispatch handler, picking a method implementation by examining the content of a selector?

July 20, 2017

Amazon Web Services – the division of Amazon that sells cloud computing services – has grown rapidly since its release in March 2006 eleven years ago. Amazon has disclosed that they have more than a million active customers every month. Due to this reach, it is important for those interested in the technology sector to understand what exactly it is.

July 18, 2017

The Free Software movement has at its core the idea that people have the freedom to use, study, share, and improve the software on their computers. The modern developer “ecosystem” has co-opted this to create a two-tier society: a developer has the freedom to use, study, share, and improve the tools and libraries that developer puts to use in creating software that must be accepted as-is, and used only in the ways permitted in the Terms of Service and End User Licence Agreement. I’ve got mine, so fuck you.

Your web application is probably split, broadly speaking, into a front-end bit that runs in the browser and a back-end bit that runs on somebody else’s computer.

The back-end bit is on somebody else’s computer, so you chose not to adopt the Affero GPL and don’t need to spill any precious freedom on the consumers of your service. The fact that you’re using Node.js (non-copyleft Free Software), a billion node modules (all most likely non-copyleft Free Software), losing your customer’s data in MongoDB (copyleft Free Software), and deploying on GNU/Linux (copyleft Free Software) with Docker (non-copyleft Free Software) and Kubernetes (non-copyleft Free Software) got you what you wanted quickly and cheaply, but there’s no need to permit anyone else access to those freedoms.

The front-end bit is on your customers’ computers, so you definitely don’t want to accidentally spill any precious freedom there! Even though you used a gallon of polyfills and shims (non-copyleft Free Software) and Angular (non-copyleft Free Software) to get what you wanted quickly and cheaply, there’s no need to permit anyone else access to those freedoms.

And of course you edited all that JavaScript with VSCode (non-copyleft Free Software).

The fact that the browser used to run that JavaScript might itself be Free Software is immaterial. The freedom to not have any freedom is not freedom.

That’s true in the mobile world too. Your free software compilers and runtimes and libraries all go to build opaque blobs that must be run as-is on somebody else’s phone, whether or not that phone has a kernel that’s Free Software. We got the bits to build our platforms and our apps quickly and cheaply, thanks to Free Software. We’ve got ours, fuck you.

But, you argue, this is all immaterial. People who aren’t developers, well, they aren’t developers, they can’t change software, why does any of this matter? Because, as all the crime dramas attest, people need motive, MO, and opportunity. Remove the freedom and the opportunity is removed: maybe someone would go out and learn a bit of programming if they had a problem they wanted to solve and the opportunity to solve it. Or maybe they’d go out and find a gigging coder, or a student who wanted a side project, or one of us pros who needs to keep their activity chart green in order to stay employable. Maybe we would benefit more from our jobs as people who change software, if there were more opportunities to change software.

The current division of software freedom into the haves and the have nots is arbitrary, artificial, and unnecessary.

July 17, 2017

Leading certificate authority Let’s Encrypt is facing criticism that its rapid growth and eagerness to encrypt internet communications is happening at a cost.

July 14, 2017

Reading List by Bruce Lawson (@brucel)

My name is Luke, I am 15 years old, in Year 10. I attend Langley Secondary School and I have spent the last week at stickee doing work experience. Originally I was not going to do my work experience week at stickee, but after my dad did some work here he told me I would […]

The post My work experience at stickee appeared first on stickee - technology that sticks.

An analysis of Amazon Web Services storage containers reveals troubling trend of misconfigured S3 buckets that leak data.

July 13, 2017

Here at stickee we are passionate about helping out and raising money for charity. Taking place on Thursday 13th July, to raise money for charity, we took on the Tour de France cycle Challenge. All the money raised was donated to the Queen Elizabeth Hospital Birmingham Charity. Through JustGiving our team and their families donated […]

The post stickee’s charity cycle challenge appeared first on stickee - technology that sticks.

July 12, 2017

Digital Birmingham Big Data Corridor: Serviceteam IT will collaborate to form partnerships with other organisations, the sharing of data and to benefit from the expertise of the partner organisations involved with the project. The possibilities are endless and Serviceteam IT can't wait to embark on this exciting new project.

July 11, 2017

We have the idea that in addition to the product development backlogs for our teams, there’s an engineering backlog where technical debt paydown, process/tooling improvements, and other sitewide engineering concerns get recorded. Working on them is done in time that is, by definition, taken away from the product backlogs (because of Sustainable Pace).

A colleague recently described the time spent on the engineering backlog as a “tax”, which is an interesting analogy. A pejorative interpretation is that, like a tax, centralised engineering work is a cost imposed that takes away from realising more value on my direct projects.

A positive spin is that taxes go toward funding the commons: no one of us can afford to build a road between our house and the office, but having roads connecting all the houses to all the offices has strategic benefit to society as a whole (higher productivity, lower unemployment, more opportunities) so if we all pay in a fraction of the cost of a road we can all have a road. Similarly, one product team might grind to a halt if they spend all of their time on the new CD pipeline infrastructure, but all teams will benefit if they all chip in a bit.

This version of the analogy implies that there might be, like the treasury, a central agency deciding how to spend the common wealth. Somebody needs to decide how much tax everyone should pay, what to do with dissenters (is it OK if your product team focuses on its sprint for a fortnight and doesn’t do any of the engineering backlog?), whether to accept overpayments, and what those tax dollars should go on.

Only it’s not tax dollars, it’s tax hours. In this sense, a better analogy is conscription (I originally thought of the Anglo-Saxon fyrd, maybe jury service or non-military national service is a less aggressive way to consider this). Taxation means that I give all of my work time to Wealth Wizards but give a chunk of my money to the government. Conscription means that I don’t get to give all of my time to my employer: some of it has to go to the commons. Maybe Jonathan and Rebecca can’t give any time to their product teams this week because they’ve been “called up” to the engineering backlog effort.

That seems like a useful analogy for these tasks. I can think about what resources are available for products or “the commons”, because I can think about whether someone is working on “the day job” or has been conscripted. Maybe it doesn’t make sense for everybody to have equal likelihood of being “called up”, in the same way that it’s easier for students to get out of jury service than for full-time employees.

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

Entering into the world of technology can be a daunting prospect for those without a prior understanding of the technical jargon involved. Cloud is one of the key buzzwords in the technology sector today, but for those that are new to the technology industry it can be difficult to get to grips with what it all means.

July 08, 2017

The key to decrypt the original Petya ransomware has been reportedly released by the ransomware’s author.

July 06, 2017

Fantastic opportunity for a passionate SysAdmin to join a forward thinking and dynamic design and development company. You will be responsible for maintaining the organisation’s servers, ensuring that they run smoothly and working with Developers to support the deployment of new applications and systems. Suitable applicants would include professionals with at least 5 years experience […]

The post SysAdmin Role appeared first on stickee - technology that sticks.

Over the course of two months last year the Copycat malware infected 14 million Android devices and rooted more than half of them, roughly eight million devices.

“Rewritten from the ground up”.

Please. Your old version mostly worked, except for those few corner cases that I’d learned how to work around. Now I don’t know whether the stuff that did work does work now, and I don’t know that I’ll find that stuff in the same place any more.

There’s a reason that old, crufty code in the core of your application was old and crufty. It is old because it works, well enough to pay the programmers who work on maintaining it and building the new things. It is crufty because the problem you’re trying to solve was not perfectly understood, is still not perfectly understood, and is evolving.

Your old, crufty code contains everything you’ve learned about your problem and your customers. And now you’re telling me that you’ve thrown it away.

July 05, 2017

There are businesses, and there are brands. But when executed well, these terms become synonymous. The likes of Apple have proved time and time again why this works. With their commitment to making stylish, minimalist and innovative technology, and with a united product line, consistency is their strongest asset. As a result, customers return with […]

The post Is your website on brand? appeared first on stickee - technology that sticks.

Reality has Levels by Andy Wootton (@WooTube)

It’s been a while since I blogged. I’ve been busy.

A major theme emerging from ‘writing my book’ is that we humans are very bad at confusing our models of reality with the reality we are modelling.

I started planning with the ‘Freemind mind-mapping tool for hierarchical brains’ before finding my own creative process had a network architecture and discovering ‘concept mapping’ which uses graphs to represent concepts and propositions. I saw that graphs were what I needed and decided to experiment with building my own software tools from bits I had lying around.

I didn’t have a current programming language, so I set out to learn Clojure. Being a Lisp, Clojure uses tree-structures internally to represent lists and extends the idea to abstractions such as collections but the only native data structures available to me appeared to be 1-dimensional.  I confidently expected to be able to find ways to extend this to 3 or more dimensional graphs but despite much reading and learning lots of other things, I’d failed to find what I was looking for. I had in mind the kind of structures you can build with pointers, in languages like ‘C’. There are graph libraries but I was too new to Clojure to believe my first serious program needed to be dependent on language extensions, when I haven’t securely grasped the basics.

This morning, I think I ‘got it’. I am trying to build a computational model of my graphical view of a mathematical idea which models a cognitive model of reality. There was always scope for confusion. Graphs aren’t really a picture, they are a set of 1-dimensional connections and potentially another set of potential views of those connections, constructed for a particular purpose. I was trying to build a data structure of a view of a graph, not the graph itself and that was a really bad idea. At least I didn’t get software confused with ‘actual’ reality, so there’s still hope for me.

Yesterday, I used Clojure/Leiningen’s in-built Test-Driven Development tool for the first time. It looks great. The functional model makes TDD simple.

I’ve got an Amazon Echo Dot, as previously mentioned. One of the things it does is the “Flash Briefing”: basically, a personalised news report. You choose “feeds” — places for it to get news — and then “Alexa, what’s new?” will read them out. I’ve got the BBC and the Birmingham weather report enabled. But I’d also like to know what’s going on in town; specifically, the Birmingham.IO calendar lists the tech events in the city and I wanted my Flash Briefing to tell me about them.

Well, now it does, handily.

To add these to your Flash Briefing, search for “Birmingham.IO” in the Skills section of the Alexa app, or enable this skill in the online Alexa Skills Store.

That was actually quite fun to do! There are some details of how it works in the source. Thank you to for giving me a place to deploy it which is HTTPS (as Alexa requires) and not Let’s Encrypt (which, moronically, Alexa doesn’t like). Questions and suggestions for improvement should be directed to the forum post. I submitted the skill and it was reviewed and accepted 24 hours later, which is nice. And there’s a promotion going on right now in the UK where if you submit a new skill during July 2017 then you get an Echo Dot, so maybe I’ll have two! Which is also pretty cool. So, what’s on tonight, Alexa?

July 03, 2017

Serviceteam IT, based in Birmingham, have confirmed the fourth consecutive year with BanaBay after delivering incremental services, initially a fibre connection, now including IP Telephony, IT Support, Office 365 Support, Cloud Backup and Business Continuity.

July 01, 2017

Reading List by Bruce Lawson (@brucel)

This reading list is sponsored by Wix Engineering, who give me money to research stuff, and when I find interesting things, I put them here.

June 29, 2017

Microsoft is warning customers of an “important” update to its Azure AD Connect service that could allow for an elevation of privilege attack against affected systems.

There’s no delicate way to say this, so I won’t try. I was having a shower, and washing the Bruce Juice Introducer™ when I discovered a hitherto unnoticed lump on my left testicle. As both my nephew and an old friend of mine have had surgery for testicular cancer, I didn’t hesitate, and phoned the doctor.

As usual, the receptionist asked what the appointment was for; I said I’d found a bollump and was given an appointment within 3 hours. My doctor thoughtfully rolled Lefty between her finger and thumb and said, “hmmm, we’ll get you a scan”. A week later, I was lying, naked from the waist down, on a table in a state of some anxiety for an ultrasound scan. I expected it to be uncomfortable – I’ve seen how hard they seem to press when scanning pregnant women. But it didn’t hurt at all; the operator maintained a constant pressure but there was none of the pain associated with any kind of pressure on the testicles.

It turned out just to be a cyst, and not cancer at all, so I apologised to the operator. “Nonsense”, she said. “Much better to spend 15 minutes here than ignore the lump. Too many men have a testicle removed – or die – because they’ve been too shy to visit the doctor early.”

And she was right. So, Gentlemen, remember this little rhyme: “If you find a lump / on your balls or your cock / don’t be a chump: / go and visit your Doc.” (And if the NHS wishes to use this rhyme and maybe turn it into a catchy jingle, for a public health advertising campaign, they can have it for free.)

June 28, 2017

Often, people shopping online add items to their baskets but leave at some point before finalising the checkout process – which is known as abandoning their shopping cart. Do you know how many people leave their cart abandoned? 69.23%, on average – but some ecommerce websites are seeing as many as 80% of their users […]

The post 3 ways to improve conversion rates on your checkout page appeared first on stickee - technology that sticks.

June 26, 2017

Separating configuration from your code itself is a good practice. Unfortunately this can quite be quite complex in itself. In fact it is fair to say that in many cases the use of DI containers to achieve this can be overkill for a task that should be rather basic.

Recently a project I've been involved with has struggled with the configuration of dependencies. This lead to the dreaded runtime error, even though at compile time everything was seemingly normal. This late feedback was compounded by the fact that getting the system up and running locally is a chore, so in many cases it was CI that was detecting these issues after a deploy.


The general practice states that your tests shouldn't need to use your production configuration. However in this case the solution was to invoke the configuration and force it to resolve. This test was odd in the sense that it does nothing other than successfully resolve. The fact that no unhandled exception is thrown is good enough. Note there is only one new test here, all other unit tests remain as-is, they are still separate from the use of the production configuration. All this test does is ensure all wiring up and dependencies are satisfied. In cases where config from an external file is used, that too will be exercised.


public void ConfigurationTest()
    var container = Container.Resolve();

The actual resolution aspect on line 5 is optional. There may be other ways to force resolution, this may vary based on what library you use. In this example only one type is resolved. If your project includes multiple entry points such as numerous controllers you may need to include these as well.

Hopefully the error that is thrown when this resolution fails is useful. Most DI libraries are fairly good in this regard. Even so it may be worth documenting this test with the steps that a developer would have to go through in order to fix.

Dynamic Languages

Even though DI libraries are a rare thing in dynamic languages, the use of a composition root is still needed. Therefore I'd recommend a similar test be applied to dynamic languages to keep the feedback loop fast.


  • Don't test your composition root in your current unit tests.
  • Do include a single test that resolves your root dependencies.
  • Include appropriate messaging to show how to fix the issue.
  • Dynamic languages should aim to test their composition root can resolve also.

June 23, 2017

The National Cyber Security Centre recommend organisations use backups as a way to help mitigate against a wide range of potentially catastrophic problems, such as fire, theft, flooding, and - naturally - ransomware.

Reading List by Bruce Lawson (@brucel)

This reading list is sponsored by Wix Engineering, who give me money to research stuff, and when I find interesting things, I put them here.

June 22, 2017

The operation behind the UK government's Cyber Essentials scheme has suffered a breach exposing the email addresses of registered consultancies, it told them today.

Websites aren’t evergreen. While your company’s site might have looked and performed perfectly back when it was first built, there’s a chance it’s not up to today’s standards. A website redesign could be the solution – from simple functional modifications to a complete overhaul of branding and design elements, there’s a solution for you. Not […]

The post 5 signs you need to redesign your website appeared first on stickee - technology that sticks.

June 21, 2017

The CSS animation-delay property is obviously used to delay the commencement of a CSS animation for a specified amount of time. But, like many CSS properties, there’s more than meets the eye… Using animation-delay you can create a variety of complex and beautiful pure CSS animations with ease, by applying it to a set of otherwise identical elements at varying time values.

All of the following examples follow the same basic setup: a number of looping animated elements are created, all of which are identical save for a unique numeric class which allows each element to be selected individually via CSS. Using this, a different animation-delay time can applied to each element, causing each animation to run asynchronously with the others to create various effects. I’ll go into more detail in the examples, below.

Basic Example: Loading Dots

See the Pen CSS animation-delay Basic Example: Loading Dots by Sebastian Lenton (@sebastianlenton) on CodePen.

This example demonstrates how to use this technique to make a simple CSS loading animation. The steps to create this are as follows:

  • Create a number of  elements all of the same class, in this case “loadingDot”. Position them however you like.
  • Create a CSS keyframe animation, and assign it to the .loadingDot class. Animate this however you like- in this instance I’m animating transform: scale.
  • Add a unique class to each element: in this case, I’ve assigned .loadingDot‑‑1, .loadingDot‑‑2 etc. (Remember that a class name cannot start with a number).
  • Finally, add the animation-delay property to each unique class, with a different delay time for each one. Ensure that the delay times are incrementing with a set interval for a cleaner looking animation (eg .10s, .20s, .30s etc), although you can choose whichever interval you like.

We can use the same technique to make more complex animations- find more examples below. Note, going forwards I will be using Sass and Haml to automate creating some of the HTML & CSS. Don’t worry if you’re unfamiliar with either of these- you can view the compiled HTML & CSS in all the following examples, which shows how it would look had it been written by hand.

Negative animation-delays: Falling Rain

See the Pen Negative animation-delay Example: Falling Rain by Sebastian Lenton (@sebastianlenton) on CodePen.

This next example uses negative animation-delay values, which has a subtly different effect to using a positive value. Using a negative animation-delay value makes an animation commence at that point during its keyframe sequence. This is essential for something like the falling rain effect above, which wouldn’t work if we had to wait for some of the elements to start animating.

The steps to create this are as follows:

  • Set html and body to 100% height.
  • Create a number of  elements all of the same class, in this case “raindrop”. The .raindrop class should use position: absolute, with top and left set to 0. Aside from that they can be styled however you like, although don’t make them too big.
  • Add a unique class to each element: in this case, .raindrop‑‑1, .raindrop‑‑2, etc). In this example I’ve used HAML to automate the above two steps, to avoid writing out large amounts of HTML manually.
  • Create a CSS keyframe animation, animating transform: translate to make an element fall from the top of the screen to the bottom.
  • Assign the keyframe animation to the .raindrop class. Ensure that a linear timing function is being used, and that the animation is set to loop infinitely.
  • Create the unique CSS class selectors (.raindrop‑‑1, etc) and add a random negative animation-delay to each one. The value doesn’t matter so much, so long as the random values are evenly spread and are lower than or equal to the animation’s duration.
  • Add a random position: left value to each unique raindrop class, in order to space the raindrops along the X-axis. Each value should be between 0% and 100%. Note, I’ve used Sass to automate the above two steps, to avoid writing out large amounts of CSS manually.

You should now be seeing a shower of raindrops falling down on your screen. This effect perhaps looks a little boring in its raw state, but with a few changes you can make more interesting effects such as a starfield or falling snow.

If you’re still confused about how negative animation-delay affects things, try flipping the animation-delay values from negative to positive and notice how the animation changes.

Fixed animation-delay Intervals: 8Bit 3D Road

See the Pen Fixed animation-delay Intervals: 8Bit 3D Road by Sebastian Lenton (@sebastianlenton) on CodePen.

This final example increments animation-delay values on a fixed interval in order to create a perfectly looping animation. The interval is calculated via (number of elements / animation duration), then each animation-delay value is set to ( interval * element number ).

Don’t worry if this sounds confusing. The following steps outline the process of constructing this animation, although we’ll be moving more quickly than before:

  • Set the body to be a 3D projection, so we can transform child elements on the Z-axis (to simulate 3D movement into the screen).
  • As previously, create a number of elements of the same class, each with an additional unique class (in this case, “roadStrip” and “roadStrip‑‑1”, etc). The roadStrip class should be positioned at the bottom of the viewport, but otherwise style it however you like.
  • Create a keyframe animation which animates a transform along the Z-axis. In this example I’m also animating opacity, to fade the roadStrips in and out at the beginning and end of the animation, although this isn’t essential. Assign this to the roadStrip class.
  • Work out your interval value by calculating animation duration / total quantity of roadStrips.
  • Apply animation-delay to each unique roadStrip class. Each animation-delay value should be calculated as interval * roadStrip ID number.

By now you should have a 3D road, moving into or out of the screen. Again, if you think the effect’s a little plain then it can be made much more exciting with just a few tweaks.

In Conclusion…

I hope you’ve enjoyed this tutorial, and learned that it’s pretty easy to create a huge amount of different animations using this technique. Drop me a line if you have any questions, and have a look through my Codepen for some more examples.

See the Pen Time Tunnel by Sebastian Lenton (@sebastianlenton) on CodePen.

The post Creating CSS Animations With animation-delay appeared first on Sebastian Lenton.

June 20, 2017

June 19, 2017

Low conversion rates and under performing pages should reveal more than just technical glitches on your website. Analysis of the customer journey and user behaviour should tell you what your online users like and dislike about their online experience. Though there is no one size fits all, trends in online behaviour reveal certain web practices […]

The post 5 things customers hate about your website appeared first on stickee - technology that sticks.

June 17, 2017

Back to Top