Technology Adoption

What Bing Chat can teach us about technology adoption

Some thoughts prompted by this great write-up about what an outstanding success Microsoft has made of integrating OpenAI’s chatbot tech into Bing: https://www.bigtechnology.com/p/wacky-unhinged-bing-chatbot-is-still

“The fact that people are even writing about Microsoft Bing at all is a win,” one Microsoft employee told me this week. “Especially when the general tenor is not negative. Like, it’s funny that it’s arguing with you over if it’s 2022 or not.”

compared to

when Google’s Bard chatbot got a question wrong in a demo last week, it lost $100 billion in market cap within hours.

Part of this is due to Microsoft’s underdog status in search. But much of it, I think, is how they have brought the users (us) along with them on the journey. They have made us think of Microsoft + ChatGPT as part of “us” vs Google being “them”.

Consider the following disasters with Large Language Models:

The common theme linking all of these. They came out of nowhere: they were launched to great fanfare and raised expectations really high.

Bing Chat couldn’t be more different. Chat GPT was released as an experimental tool, got feedback from early users and rapidly iterated to improve the initial versions. It got us onside and loving it despite its flaws.

Then Microsoft announced their mega investment, getting us also more invested in the product, and creating excitement about implementing it into Bing.

Finally, Microsoft iterated at pace to get something working into their product, building on the excitement and momentum that we, the users, were generating.

So when it finally released, we were really excited and keen to use it (witness the app download stats) and sympathetic to its deficiencies, or, perhaps we even enjoyed the deficiencies.

Some obvious lessons in here about telegraphing your intentions early, bringing your users along with you and iterating at pace.

Product Management, Software Development

Agile Software Development 22 years on

The Agile Manifesto came about in Feb 2001. That makes it 22 years old now. There are people commercially writing code today who weren’t even born when it came out.

Goodness, I feel old.

The values that underpin the Agile Manifesto remain sound and the best way to approach your software development. But I have seen many times that in an effort to ‘do agile’, teams lose the ability to ‘be agile‘.

If you want to avoid this trap, bear in mind the context that the Agile Manifesto came out of.

Conventional wisdom at the time was was, for example, spend 1 month scoping the project, 3 months documenting requirements, 12 months building, 3 months testing and 6 months rolling out. This sort of order of things. With checkpoints at each step along the way.

There was a whole generation of project managers who prided themselves on delivering projects on time, on budget, on scope. I was one of them. Yet at the same time, the companies investing in tech would complain of over-runs in all of these factors.

Why the disconnect? Because of the focus on scope (building features) rather than impact (solving problems). As a project manager working in one of these projects you could build a successful career by agreeing a scope, writing it down and delivering it. Then, when the inevitable changes arose you’d handle those as individual ‘change orders’, each adding more scope which you would then deliver on time, on budget and so forth (and get paid more for doing). But the users would end up paying many times as much as initially expected over a much longer timescale before they saw the benefits that they had been looking for.

Agile changed all that by, basically, saying “let’s talk more between the programmers and the users and let’s deliver in smaller increments so we can keep focus on the most important things”.

That was the kernel and the genius of Agile.

At some point things started to go wrong. In my view it’s when Agile became equated with Scrum; anything non-scrum became called Waterfall and therefore not to ever be mentioned again.

Agile is not a methodology. Agile isn’t something you do. Agile is something that following those 4 simple values can help you be.

So as we look back on the arrival of Agile on the scene all those years ago, I urge you to forget about your Kanban and Scrum and Roadmaps and Mob Programming for a moment and just remind yourself of the 4 key values that can sit underneath all these attempts to become more agile in how we build software:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

https://agilemanifesto.org/

Software Development

Sometimes I miss Haskell’s immutability

I have ‘fond’ memories of tracking down a particularly PITA bug in some Python code.  It was down to whether using = makes two references to the same underlying object, or whether it makes a copy of the object in question. And equally fond memories of debugging a ruby function that changed a hash unexpectedly.

This sort of thing:

>>> arr = [1,2,3]
>>> arr2 = arr
>>> arr
[1,2,3]
>>> arr2
[1,2,3]
>>> arr == arr2
True # Values are equivalent, objects are also the same
>>> id(arr)
4469618560 # the id for both arr and arr2 is the same: they are the same object
>>> id(arr2)
4469618560
>>> arr2.append(4)
>>> arr
[1,2,3,4]
>>> arr2
[1,2,3,4]

compared to

>>> arr = [1,2,3]
>>> arr2 = [1,2,3] + [] # arr2 is now a different object
>>> arr
[1,2,3]
>>> arr2
[1,2,3]
>>> arr == arr2
True # Values are the same even though the object is different
>>> id(arr)
4469618560
>>> id(arr2)
4469669184 # value is different
>>> arr2.append(4)
>>> arr
[1,2,3]
>>> arr2
[1,2,3,4]

Or, in a case that you’re more likely to see in the wild

>>> arr = [1,2,3]
>>> d1 = {"foo":arr, "bar": "baz"}
>>> d2 = d1
>>> d3 = dict(d1) # Creates new dict, with its own id
>>> id(d1)
140047012964608
>>> id(d2)
140047012964608
>>> id(d3)
140047012965120
>>> arr.append(4)
>>> d1["bar"] += "x"
>>> d1
{'foo': [1, 2, 3, 4], 'bar': 'bazx'}
>>> d2
{'foo': [1, 2, 3, 4], 'bar': 'bazx'}
>>> d3
{'foo': [1, 2, 3, 4], 'bar': 'baz'}

d1 and d2 are the same dict so when you change the value of bar, both have the same result, but d3 still has the old value. But, even though the dicts are different, the arr in them is the same one. So anything that mutates that list will change it in all the dicts

This sort of behaviour has its logic but it is a logic you have to learn, and a logic you often have to learn the painful way. I particularly ‘enjoy’ cases where you’ve gone to great lengths to make sure the object is a copy and then find that something inside that list gets mutated.

It doesn’t have to be like this.

In what is probably the most beautiful language I’ve ever used (though sadly only in personal projects, not for work), Haskell, everything is immutable.

If you’ve never tried Haskell this might sound incomprehensible, but it’s just a different approach to programming. Two good links about this:

Immutability is Awesome

What does immutable variable in Haskell mean

This language feature eliminates a whole class of bugs related to changing an object unexpectedly. So I’d encourage any software developers to try to get their heads around a language like Haskell. It opened my eyes to a whole different approach to writing code (e.g. focussing on individual functions rather than starting with a db schema and working out from there).