Skip to content


SAFe Version 3.0 Available Through December 2016

Agile Product Owner - Fri, 01/01/2016 - 21:03
SAFe 3.0, Release Date July 28, 2014SAFe 3.0, Release Date July 28, 2014

The new version of the Framework, SAFe 4.0 for Lean Software and Systems Engineering, provides greater modularity than its predecessor with a dynamic collapse/expand capability. The collapsed view, “3-Level SAFe,” is backwards compatible with Version 3.0, preserving the skill sets of current SAFe practitioners, and providing an easy upgrade path for enterprises invested in the 3.0 version of the Framework.

We encourage you to upgrade to SAFe 4.0 to take advantage of the new features, but recognize that there are enterprises that will need the ‘classic’ 3.0 version for some time to come, so it will be supported throughout 2016, and is available at

The complete set of 3.0 courseware—Leading SAFe, SAFe Scrum XP, PM/PO, and PPM—will continue to be available as well.

Read more about the new Framework at What’s New in SAFe 4.0.

—The SAFe Team

Categories: Blogs

Explore Out of the Box

Evolving Excellence - Fri, 01/01/2016 - 18:30

Unless you try to do something beyond what you have already mastered, you will never grow. – Ralph Emerson

It’s that arbitrary time of the year when many folks reflect on the past and set goals for the coming year.  I enjoy reading how other people in the Lean world approach this activity as planning, hoshin, and reflection, hansei, are core components of Lean.  Karen Martin just went into hers with some nice detail, and I especially like the ritualistic aspect of her process.  Matt May has described his in the past as well, with a nod to Seth Godin’s “shopping list” concept.

I have a similar process that I’ve alluded to in a few previous posts.  Each year toward the end of December my wife and I take a vacation to someplace nice and quiet.  Instead of playing tourist to visit a bunch of new places like we usually do in the summer, this trip is purposely to have some R&R, reconnect, and recenter.  This latest one, from which I returned just last night, was two weeks at a beach house on Nevis, with nothing to do except relax, eat, talk, and watch the sunset.  And, for me, perform my annual ritual.

I take a look at my journal – a well-worn Moleskine (usually volumes 1, 2, and 3 by the end of the year), compare the plan to what happened, read the notes, and generally reflect on the year.  Although the process has weekly, monthly, and quarterly components, the end-of-year reflection is the most intense.  What did I achieve, what did I miss, what countermeasures do I need to put into place, and what should I do the next year.

This is all fairly standard, and many folks do it.  It eventually turns into what I call “My Shibumi” – after Matt May’s book, The Shibumi Strategy, and also because it somehow makes me think of My Sharona by The Knack, a band I unexpectedly partied with a couple decades ago.  I create key goals for the upcoming year, usually a couple each in categories such as physical, emotional, spiritual, intellectual, and professional.

But the most important goal I set is my “do something different” goal.  This is the one that stretches me out of my comfort zone, challenges my perspectives and biases, and helps turn me into a well-rounded human and citizen of the planet.

I’ve had this type of annual goal for about twenty years, initially informally but very formal for the past decade or so.  Earlier ones were fairly physical, like ski five European countries in six days, learn to windsurf, dive, and hang glide, and run a full marathon.

As I’ve become older they have become more intellectual, such as a deep dive into Buddhism and last year’s exploration of the history of the Bible.  I read over a dozen books on the topic, and it really opened my eyes to the complexity of the 500,000 variants resulting from intentional and unintentional translation and transcription errors, Church politics, and archeological methods.  I’ve also learned to program HTML, rebuilt a 1973 Triumph Spitfire, explored being vegan and vegetarian (ending up as a “pescatarian” for the past decade), and quit a great job at a great company to do my own thing.

I’m by far not the only one that creates such annual stretch goals.  Consider Facebook’s Mark Zuckerberg.  He has had goals to learn Mandarin, meet a new person each and every day, only eat meat he butchered himself, and write one thank you note each day.

He choses the goal after an analysis of the gap between where he is and where he wants to be.  A key outcome is that he learns something new, and often unexpected. Trying to learn Mandarin taught him that he didn’t listen well and a year of killing animals made him consider becoming vegetarian. The goal to meet a new person each day, which he achieved by giving face-to-face chats at schools, helped him understand the personal side of problems with immigration policy. Those secondary effects are often more important and meaningful than the original goal itself.

So what’s my goal for 2016?  I toyed with the perennial “get into shape” but after only a couple months on Paul Aker’s Lean Health program, I’ve lost over 15 pounds and am in the best shape I’ve been since the 1990s.  If you want to get into shape by leveraging Lean, get his new book.  I also thought about a deep dive into minimalism and simplicity, but my wife and I have been doing that at a less intense level for several years so I decided it wasn’t radical enough. The slow and steady improvement was working well.  I’ve wanted to finish a book on the nexus of Lean and Zen, but I pretty much did that also while on Nevis (stay tuned!), so that’s out.

One Hundred Years of SolitudeI’ve decided on another intellectual pursuit to broaden my horizons.  I’m going to read one of the top works of literature from each of the major ethnic groups or geographical areas – European, Latin American, Chinese, Hindustani, Arabic, African, and so forth.  It should work out to roughly one a month.  I’ve decided to start this month with Latin American.  Since I’ve already read several books by Mario Vargas Llosa, a Nobel Prize winner I met in Peru many years ago, the first one will be One Hundred Years of Solitude by Gabriel Garcia Marquez, also a Nobel Prize winner.

How will you explore out of the box this year? Perhaps more importantly, how will you ensure you actually do it, and why?  You’ll probably be amazed at what you learn about yourself – and the world.

Categories: Blogs

Pretend they are mind reading

Thought Nursery - Jeffrey Fredrick - Fri, 01/01/2016 - 11:30

At the prompting of Douglas Squirrel I just read Yossi Kreinin‘s blog post People can read their manager’s mind. This seemingly magical power is the mundane result of combining “People generally don’t do what they’re told, but what they expect to be rewarded for”, and people are good at spotting what is actually rewarded. As a manager/leader I’m taking away a heuristic I want to test:  when I’m not able to get alignment with my stated goals I’m going to pretend the team is reading my mind, and that they are heeding my hidden thoughts rather than my words. From that mindset, what does that suggest about my own values? The results aren’t likely to be flattering. I embrace the idea that “the only way to deal with the problems I cause is an honest journey into the depths of my own rotten mind.

(As much as I embrace that message for myself, I’d warn non-managers from seeking solace in the article, from using it as a shield to deny their own accountability. Yes, the article says that it is an “insane employee” who will work to fix important but unglamorous problems, and that “the average person cannot comprehend the motivation of someone attempting such a feat”. Do you find solace in being average? In being powerless? I don’t. I think it is worth always seeking to improve, and to improve the organization I’m part of. I believe someone out there could improve the situation I’m in, so if I’m frustrated it is probably my fault.)

Categories: Blogs

The Best Books I Read in 2015

J.D. Meier's Blog - Thu, 12/31/2015 - 20:56

Back by popular demand, here is my Best Books I Read, 2015 edition:

The Best Books I Read in 2015

As you may know, I read a lot of books.  I find it’s the best way to keep up and get ahead at Microsoft. 

I don’t just read technical books.  I read a wide variety of books, including mind, body, emotions, career, finance, relationships, and fun.

The common theme across the board is how to hack a better you.

I find that the more I learn across the board, the easier it gets to improve productivity, personal effectiveness, and impact at work.  And the bonus is that this spills into life.

This year, I spent extra effort on more health hacking.  We’re up against some pretty bad odds … 1 in 3 people die of cancer, but it used to be 1 in 80.  I in 4 get diabetes, but it used to be 1 in 4,000.  The good news is that there is some tremendous insight if you know the right books.

I also spent some extra energy focused on disruptive  innovation and digital transformation.  Again, some things can seem like magic until you know how the magic is done.  All of the magic tricks are revealed if you know the right books to read.

The Best Books I Read in 2015 is effectively the short-list from the very long list of books that I read in 2015.  Reading has always been one of the best ways for me to learn new ideas and new things to try.  I continue my quest for the world’s best insight and action for work and life, and I hope that some of the books I’ve included in my list turn out to be game changers for you.


Categories: Blogs

2015: A year in the life of the Neo4j London meetup group

Mark Needham - Thu, 12/31/2015 - 15:58

Given we’ve only got a few more hours left of 2015 I thought it’d be fun to do a quick overview of how things have been going in the London chapter of the Neo4j meetup using Neo4j with a bit of R mixed in.

We’re going to be using the RNeo4j library to interact with the database along with a few other libraries which will help us out with different tasks:

graph = startGraph("http://localhost:7474/db/data/", username = "neo4j", password = "myPassword")

Let’s get to it:

query = "MATCH (:Group {name: {name}})<-[membership:MEMBER_OF]-()
         RETURN membership.joined AS timestamp"
joinedDF = cypher(graph, query, name = "Neo4j - London User Group")
joinedDF$joinDate = as.Date(as.POSIXct(joinedDF$timestamp / 1000, origin="1970-01-01"))
joinedDF$joinDate = as.Date(as.POSIXct(joinedDF$timestamp / 1000, origin="1970-01-01"))
ggplot(aes(x = year, y = n, label = n), 
       data = joinedDF %>% mutate(year = format(joinDate, "%Y")) %>% count(year)) + 
  geom_bar(stat = "identity", fill = "Dark Blue") + 
  ggtitle("Number of new members by year") +
2015 12 31 12 23 06

A bit down on 2014 but not too far away. We’re still attracting new people who are interested in learning about graphs. Let’s drill into those numbers a bit:

byYearMon = joinedDF %>% 
  filter(format(joinDate, "%Y") == 2015) %>% 
  mutate(yearmon = as.Date(as.yearmon(joinDate))) %>% 
ggplot(aes(x = yearmon, y = n, label = n), data = byYearMon) + 
  geom_bar(stat = "identity", fill = "Dark Blue") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  scale_x_date(labels = date_format("%B"), breaks = "1 month") +
  ggtitle("Number of new members by month/year")
2015 12 31 12 39 04

We had a bit of an end of year surge in October/November which was unexpected. December has been low in previous years, there was an April dip which I think is because we stopped doing events before Graph Connect 2015. I’m not sure about the September dip so let’s have a look:

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)
               RETURN event.time + event.utcOffset AS timestamp"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group")
eventsDF$timestamp = as.Date(as.POSIXct(eventsDF$timestamp / 1000, origin="1970-01-01"))
eventsByYearMon = eventsDF %>% 
  filter(format(timestamp, "%Y") == 2015) %>% 
  mutate(yearmon = as.Date(as.yearmon(timestamp))) %>% 
merge(eventsByYearMon, byYearMon, by="yearmon")
      yearmon n.x n.y
1  2015-01-01   3  80
2  2015-02-01   6  76
3  2015-03-01   2  70
4  2015-04-01   2  53
5  2015-05-01   4  78
6  2015-06-01   5  83
7  2015-07-01   3  73
8  2015-08-01   5  73
9  2015-09-01   3  40
10 2015-10-01   3  94
11 2015-11-01   4 117
12 2015-12-01   3  48

At first glance there doesn’t seem to be any correlation between the number of events held and the number of new members so I think we’ll have to look for another predictor of that variable!


Next let’s have a look at the events we ran in 2015. We’ll start with a quick chart showing the number of events we’ve run over the years:

ggplot(aes(x = year, y = n, label = n), data = eventsDF %>% mutate(year = format(timestamp, "%Y")) %>% count(year)) + 
  geom_bar(stat = "identity", fill = "Dark Blue") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  ggtitle("Number of events")

2015 12 31 13 43 15

So less events than last year but how many people RSVPD ‘yes’ to the ones we did host?

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)<-[:RSVPD {response: 'yes'}]-()
               WHERE event.time + event.utcOffset < timestamp()
               WITH event, COUNT(*) AS rsvps
               RETURN event.time + event.utcOffset AS timestamp, rsvps"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group")
eventsDF$timestamp = as.Date(as.POSIXct(eventsDF$timestamp / 1000, origin="1970-01-01"))
ggplot(aes(x = year, y = rsvps), 
       data = eventsDF %>% mutate(year = format(timestamp, "%Y")) %>% group_by(year) %>% summarise(rsvps= sum(rsvps)) ) + 
  geom_bar(stat = "identity", fill = "Dark Blue") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  ggtitle("Number of attendees")
2015 12 31 13 54 50

Slightly more ‘yes’ RSVPs than last year. Now let’s drill into the repeat events we ran this year:

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)
               WHERE {startYear} <= (event.time + event.utcOffset) < {endYear}
               RETURN AS event, COUNT(*) AS times
               ORDER BY times DESC"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group", 
                  startYear  = as.numeric(as.POSIXct("2015-01-01", format="%Y-%m-%d")) * 1000, 
                  endYear = as.numeric(as.POSIXct("2015-12-31", format="%Y-%m-%d")) * 1000)
eventsDF %>% filter(times > 1)
                                                       event times
1                      Relational to graph: A worked example     7
2                                            Intro to Graphs     6
3                          Graph Modelling - Do's and Don'ts     5
4          Hands On Intro to Cypher - Neo4j's Query Language     3
5 Build your own recommendation engine with Neo4j in an hour     2
6                                Fraud Detection using Neo4j     2

I thought we’d run ‘Intro to Graphs’ most often but the data doesn’t lie – it’s all about relational to graph. And which were the most popular repeat events in terms of ‘yes’ RSVPs?

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)
               WHERE {startYear} <= (event.time + event.utcOffset) < {endYear}
               MATCH (event)<-[:RSVPD {response: 'yes'}]-()
               WITH event, COUNT(*) AS yesRSVPs
               WITH AS event, COUNT(*) AS times, SUM(yesRSVPs) AS rsvps
               RETURN event, times, rsvps, rsvps / times AS rsvpsPerEvent
               ORDER BY rsvpsPerEvent DESC"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group", 
                  startYear  = as.numeric(as.POSIXct("2015-01-01", format="%Y-%m-%d")) * 1000, 
                  endYear = as.numeric(as.POSIXct("2015-12-31", format="%Y-%m-%d")) * 1000)
eventsDF %>% filter(times > 1)
                                                       event times rsvps rsvpsPerEvent
1                                Fraud Detection using Neo4j     2   150            75
2                                            Intro to Graphs     6   352            58
3                          Graph Modelling - Do's and Don'ts     5   281            56
4                      Relational to graph: A worked example     7   367            52
5 Build your own recommendation engine with Neo4j in an hour     2    85            42
6          Hands On Intro to Cypher - Neo4j's Query Language     3   104            34

It looks like fraud is a popular topic although we’ve only run it twice so perhaps best not to read too much into that. We’re running that one again in a couple of weeks if you’re interested.

Ignoring repeat events let’s see which event drew the biggest crowd:

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)
               WHERE {startYear} <= (event.time + event.utcOffset) < {endYear}
               MATCH (event)<-[:RSVPD {response: 'yes'}]-()
               WITH AS id, AS event, COUNT(*) AS rsvps
               RETURN event, rsvps
               ORDER BY rsvps DESC"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group", 
                  startYear  = as.numeric(as.POSIXct("2015-01-01", format="%Y-%m-%d")) * 1000, 
                  endYear = as.numeric(as.POSIXct("2015-12-31", format="%Y-%m-%d")) * 1000)
eventsDF %>% head(5)
                                                                         event rsvps
1 Neo4j Full Stack Applications + Python, R and Neo4j - The Data Science Stack   133
2                          Modelling a recommendation engine: A worked example   118
3                    Building a repository of biomedical ontologies with Neo4j   107
4                     GraphHack @ Graph Connect: The night before Election Day    91
5                                        Bootstrapping a Recommendation Engine    88

A double header featuring Nicole White and Matt Wright proved to be the most popular event of the year and in fact the most popular in terms of ‘yes’ RSVPs so far:

eventsQuery = "MATCH (:Group {name: {name}})-[:HOSTED_EVENT]->(event)<-[:RSVPD {response: 'yes'}]-()
               WITH event, COUNT(*) AS rsvps
               RETURN AS event, event.time + event.utcOffset AS time, rsvps
               ORDER BY rsvps DESC"
eventsDF = cypher(graph, eventsQuery, name = "Neo4j - London User Group")
eventsDF$time = as.Date(as.POSIXct(eventsDF$time / 1000, origin="1970-01-01"))
eventsDF %>% mutate(year = format(time, "%Y")) %>% dplyr::select(-time) %>% head(10)
                                                                          event rsvps year
1  Neo4j Full Stack Applications + Python, R and Neo4j - The Data Science Stack   133 2015
2                           Modelling a recommendation engine: A worked example   118 2015
3                     Building a repository of biomedical ontologies with Neo4j   107 2015
4                                                    Real world Neo4j use cases    98 2014
5                                                           The transport graph    94 2014
6                                                     The Visualisation Special    93 2014
7                  Impossible is Nothing by Jim Webber, Neo4j's Chief Scientist    93 2014
8                      GraphHack @ Graph Connect: The night before Election Day    91 2015
9                                         Bootstrapping a Recommendation Engine    88 2015
10                                    Scraping and Graphing the Apple app store    88 2015

3 of the top 4 belong to 2015 and 6 of the top 10. Let’s see what 2016 has in store.

Thanks to everyone who’s come along to one of our meetups and Happy New Year!

Categories: Blogs

Study until your mind wanders

Mark Needham - Thu, 12/31/2015 - 12:47

I’ve previously found it very difficult to read math heavy content which has made it challenging to read Distributed Computing which I bought last May.

After several false starts where I gave up after getting frustrated that I couldn’t understand things the first time around and forgot everything if I left it a couple of days I decided to try again with a different approach.

I’ve been trying a technique I learned from Mini Habits where every day I have a (very small) goal of reading one page of the book. Having such a small goal means that I can read the material as slowly as I like (repeating previous days if necessary).

So far I’ve read 4 chapters (~100 pages) over the last month – some days I read 6 or 7 pages, other days I only manage one. The key is to keep the rhythm of reading something.

I tried doing the reading at different times of the day – on the bus on the way to work, in the evening before going to sleep – and found that for me the best time is immediately when I wake up. To minimise my mind wandering I don’t read any emails, chat messages or social media accounts before I start.

Despite this, I’ve noticed that after a while my mind starts to wander while reading proofs and that’s a signal for me to stop for the day. When I pick up again the next day I’ve often found that I understand what I was having difficulty with.

I’ve read that meditation prior to studying is an effective way to quiet the mind and would be a more ‘on demand’ way of achieving the concentration required to read this type of material. I’ve never done any meditation so if anyone has any tips on where to start that’d be helpful.

Categories: Blogs

Playing to Win in Software

Thought Nursery - Jeffrey Fredrick - Thu, 12/31/2015 - 11:46

Subtitle: Lessons learned from video games

This past year I’ve spent a lot of my time on Action Science as a route to organizational learning, and one of the real insights I’ve had is how painful it is to learn. Learning, according to Chris Argyris, is the detection and correction of error. The emotionally difficult part is detecting our own errors, in being genuinely open to the idea that we are part of why things aren’t working better than they are. In my view a professional should cultivate the mindset that they need to improve. Otherwise they risk being a “scrub”.

Slides (pdf): Playing to Win in Software

This talk was delivered January 10th, 2013 at TIM Group as part of their Thursday lightning talk series.



Categories: Blogs

Early Impressions of Kotlin

Mistaeks I Hav Made - Nat Pryce - Thu, 12/31/2015 - 01:07
We’ve been using the Kotlin programming language for a few weeks on our latest project to perform technical experiments, explore the problem space, and write a few HTTP services. I’ve also ported Hamcrest to Kotlin, as HamKrest, to help us write tests, and written a small library for type safe configuration of our services. Why Kotlin? The organisation I’m working with has mature infrastructure for deploying JVM services in their internal PaaS cloud. They use a mix of Java and Scala but have found Scala builds too slow. Watching my colleague struggle to use Java 8 streams to write what should have been basic functional map-and-fold code, I decided to have a look at some other “post-Java” JVM languages. We wanted a typed language. We wanted language aware editing. And we wanted a language that had an organisation behind its development and enough people using it that we could get questions answered, even the stupid ones we’d be likely to ask while learning. That eliminated dynamically typed languages (Groovy, JavaScript, Clojure) and languages that are less popular or have small, informal development teams behind them (Xtend, Gosu, Fantom, Frege, etc.). In the end it came down to Red Hat’s Ceylon and JetBrains’ Kotlin. Of the two, Ceylon is the most innovative, and therefore (to me, anyway) the most interesting, but Kotlin met more of our criteria. Kotlin has a more active community, is being used for commercial development by JetBrains and a number of other companies1, has good editing support within IntelliJ, has an active community on social media, and promises easy interop with existing Java libraries. Good points Kotlin was very quick to learn. Kotlin is a conservative increment to Java that smooths off a lot of Java’s rough edges. Kotlin is small and regular, with few special cases and gotchas to learn. In many ways it feels a bit like a compiled, typed Python with curly brace syntax. The type system is a breath of fresh air compared to Java. Type inferencing makes code less cluttered. There is no distinction between primitive & reference types. Generics and subtyping work together far better than Java: the type system uses declaration site variance, not use site variance, and variance does not usually have to be specified at all for functions. You never have unavoidable compiler warnings, as you do with Java’s type system. Functional programming is more convenient in Kotlin than Java. You can define free-standing functions and constants at the top level of a module, instead of having to define them in a “Utils” class. Function definitions can be nested. There is language support for immutable value types (aka “data classes”) and algebraic data types (“sealed classes”). Null safety is enforced by the type system and variables and fields are non-nullable by default. The language defines standard function types and a lambda syntax for anonymous functions. You can define extension methods on existing types. They are only syntactic sugar for free-standing functions, but nevertheless can lead to more concise, expressive code. The Kotlin standard library defines a number of useful extension methods, especially on the Iterable and String types. Kotlin supports, and carefully controls, operator overloading. You can overload operators that act as functions (e.g. arithmetic, comparison, function call) but not those that perform flow control (e.g. short-cut logical operators). You cannot define your own operators, which will stop me going down the rabbit hole of “ascii-art programming”, which I found hard to resist when writing Scala. Class definitions require a lot less boilerplate than in Java. Using old fashioned getter-and-setter style Java code is made more convenient by language support for bean properties. Anonymous extension methods (borrowed from Groovy, I believe) make domain specific embedded languages easier to write. Method chaining builder APIs are unnecessary in Kotlin and more awkward than using the apply function to set properties of an object. Kotlin has a philosophy of preferring behaviour to be explicitly specified. For example, there is no automatic coercion between numeric types, even from low to high precision. That means you have to explicitly convert from Int to Long, for example. I like that, but I expect some people will find it annoying. Surprises I didn’t miss destructuring pattern match Kotlin doesn’t have destructuring pattern match & language support for tuples. A limited form of destructuring can be used in for loops and assignments. The when expression is an alternative conditional expression that doesn’t do destructuring. I was surprised to find that I didn’t really miss destructuring. Without tuples you have to use data classes with named fields. The flow-sensitive typing then works rather well where destructuring would be necessary in a language where the type system is not flow-sensitive. For example: sealed class Result { class Success(val value: T) : Result() class Failure(val exception: Throwable): Result() } ... val e : Result = doSomething() if (e is Result.Success) { // e is known to be a Result.Success and // can be used as such without a downcast println(e.value) } Sealed classes cannot be data classes An algebraic data type cannot be be a data class, so you have to write equals, hashCode, etc. yourself. This is a surprising omission, since I always want an algebraic data type to be a value type. The Kotlin developers say that this will be fixed after version 1.0 is released. Functions are not quite first-class objects There’s a difference between f1 and f2 below: val f1 = {i:Int -> i+1} fun f2(i:Int) = i + 1 Code can refer to the value of f1 directly, but must use the “::” operator to obtain a reference to f2: val f = ::f2 Null safe operators push me to write more extension functions The null safe operators (?. and ?:) only help when dereferencing a nullable reference. When you have a nullable reference and want to pass a value (if it exists) to a function as a parameter, you have to use the awkward construct: nullableThing?.let{ thing -> fn(thing, other, parameters) } I find myself refactoring my functions to extension functions to reduce the syntactic noise, letting me rewrite the code above as: nullableThing?.fn(other, parameters) Is that a good thing? I’m not sure. Sometimes it feels a little forced. Companion objects Kotlin borrows the concept of companion objects from Scala. Why can’t classes be objects? Perhaps it’s a limitation of the JVM but compared to, say, Python, it feels clunky. Frustrations I only have a couple of frustrations with Kotlin. Lack of polymorphism Operators and the for loop are syntactic sugar that desugar to method calls. The methods are invoked statically and structurally — the target does not need to implement an interface that defines the method. For example, a + b desugars to a.add(b). However, there’s no way to write a generic function that sums its parameters, because add is not defined on an interface that can be used as an upper bound. There’s no way to define the following function for any type that has an add operator method. fun sum(T first, T second) : T = first + second You would have to define overloads for different types, but then wouldn’t be able to call sum within a generic function. fun sum(first: Int, second: Int) = first + second fun sum(first: Long, second: Long) = first + second fun sum(first: Double, second: Double)= first + second fun sub(first: Matrix, second: Matrix)= first + second fun sum(first: Money, second: Money)= first + second ... That kind of duplication is what generics are meant to avoid! Extension methods are also statically bound. That means you cannot write a generic function that calls an extension method on the value of a type parameter. For example, the standard library defines the same extension methods on unrelated types — forEach, map, flatMap, fold, etc. But there is no concept of, for example, “mappable” or “foldable”. Nor is there a way of defining such a concept and applying it to existing types to allow you to write generic functions over unrelated types. Kotlin doesn’t have higher kinded types that would let you express this kind of generic function or type classes that would let you add polymorphism without modifying existing type definitions. Compared to Rust’s traits, which support extension methods, operator overloading, type classes for parametric polymorphism, and interfaces for subtype polymorphism, Kotlin’s monomorphic extension methods and operator overloading are quite limited and do not help refactor duplicated logic. However, for typical monomorphic, procedural Java code this is probably not an issue. Optionality is a Special Case Kotlin’s support for nullable types is implemented by a special case in the type system and special case operators that only apply to nullable references. The operators do not desugar to methods that can be implemented for other types. For example, optionalThing?.foo can be considered a map of the function {thing ->} over the option optionalThing. If foo itself is nullable, then it can be considered a flatMap. But the expressions do not desugar to map and flatMap And if you want to map or flatMap a function, you have to use a different syntax: optionalThing?.let(theFunction). For typical Java code, which is monomorphic and uses null references with wild abandon, language support for nullability is invaluable. But I would find it more convenient if it could be used polymorphically, or if Kotlin used a common naming convention for optional and other functor types. Null safety is not enforced when you interop with Java code. And you do that a lot. Kotlin doesn’t have many libraries or much of a runtime and makes it easy to call existing Java libraries directly. Kotlin expects you to know what you’re doing with respect to null references when calling Java code, and doesn’t force you to treat every value returned from Java as nullable. As a result, null safety is a bit of an illusion in a lot of our Kotlin code and it has come back to bite us. Conclusion The code we’ve been writing has been a mix of coordinating and piping data between existing Java libraries – Apache HTTP client, Undertow HTTP server, JDBC, Sesame, JSON and XML parsers, and so on – and algorithmic code that analyses human readable text. For that kind of work, Kotlin has been very useful. The Kotlin code is far more concise than the equivalent Java. In our domain models and algorithmic code, Kotlin’s type safety and especially null safety, has been a big help. Exactly how happy we’ve been with Kotlin has depended on the design style of the code we’re writing: For functional programming, Kotlin has occasionally been frustrating, because we cannot use parametric polymorphism to factor out duplicated logic as much as we’d like. For object-oriented programming, Kotlin’s concise syntax for class definitions and language support for delegation avoids a lot of Java’s boilerplate. However, most Java out there is monomorphic, procedural code moving data between “NOJOs” and APIs that expect objects to have “bean” getters and setters. Kotlin has made working with that kind of API much easier and far more concise than doing so in Java. As far as I can tell, RedHat sponsor development of Ceylon but do not actually use it to develop their own products. If I’m wrong, please let me know in the comments.↩
Categories: Blogs

Want to Write Non-Fiction Better?

Johanna Rothman - Wed, 12/30/2015 - 18:44

If you write as part of your job, I have a new online workshop starting in March. It’s Writing Workshop 1: Write Non-Fiction to Enhance Your Business and Reputation.

Here’s the problem I see. You’re a consultant or other entrepreneur. You know you need to write to enhance or build your reputation. You see a blank page (paper or screen), and you have no idea what to write. Maybe you can start, but you get 23 words in and get stuck. Maybe you get 5,000 words in, and you know there’s good work in there, but you can’t see it.

If you would like to address these challenges (and more), and deliver non-fiction articles, blog posts or newsletters to your readers, this workshop is for you.

You’ll learn:

  • How to make writing a habit.
  • How to structure an article that people want to read.
  • Write articles or blog posts or whatever that engage your ideal reader and build your reputation.
  • What writing is. What editing is. How they are different.
  • How to decide when to place your writing where.

You will write during this workshop. We will focus on short non-fiction, such as blog posts and articles.

I am the only person who will read your writing. I have published over 500 articles and well over 1500 blog posts. I write two columns each month and two quarterly columns each year. (If you have ever been part of a critique group, you know sometimes they savage you with feedback. I won’t do that.) I am a professional technical editor, as well as a writer.

I am focusing this workshop for people who know that writing will enhance their professional prospects, who have trouble publishing finished work. You will learn many ways to structure your work and publish. If you do the homework, you can expect that you will finish at least one article, as part of this workshop.

Want to join us? See Writing Workshop 1: Write Non-Fiction to Enhance Your Business and Reputation for full details and signup.

Categories: Blogs

Introducing Dr. Raymond Boehm, the Agile Estimator

Agile Estimator - Wed, 12/30/2015 - 18:14


The agile estimator blog is focused on estimating agile software development projects. Occasionally, it may stray into estimating in general. Likewise, it may talk about agile software development in general.

It is primarily moderated by Ray Boehm. He has the following qualifications:

  • Academically, he has an M.B.A. in finance and a Doctor of Professional Studies in computing. His thesis was “An Approach to Early Lifecycle Estimating for Agile Projects.”
  • Experientially, he has been involved in software development since the seventies. In the eighties, his focus became methodology, estimating, sizing and quality assurance. In 2003, he became involved in agile development when he started work on his doctorate. Since then, he has continued to be involved in the sizing and estimating of agile development projects.
  • Regarding certifications, he is an IFPUG Certified Function Point Specialist (CFPS) Fellow and a Certified SNAP Practitioner (CSP). He is also a Quality Assurance Institute (QAI) Certified Software Quality Analyst (CSQA)
Categories: Blogs

Running a Personal Retrospective for 2015 - Wed, 12/30/2015 - 13:59

It’s the end of yet another year and a great time to reflect and put your Personal Retrospective hats on. I mention using Personal Retrospectives in my book, “The Retrospective Handbook: A guide for agile teams” because I find them powerful tools to celebrate the past year and to establish new goals for a new year.

This year, instead of simply stepping through questions on paper or on the computer, I decided to use sticky notes and activities I would use with a larger group. In order to keep flow, I wanted to prepare appropriately. This meant I:

  1. Made a plan for the exercises I wanted to run;
  2. Prepared the activities in advance so I could focus on gathering data/generating insights and reflecting instead of thinking about the process;
  3. Had a set of questions prepared in case I got stuck;
  4. Put on some background music – a quick search on YouTube found this spiritual landscape music; and
  5. Had water and coffee ready so I didn’t need to leave the room.

Here are the activities I used this year and that you might find useful for your own Personal Retrospective.

A year in tweets

Using very small stickies to simulate the 140 character limit (I’m guessing I had ~50) trying to generate a number of small tweets about how I felt about 2015.

 A year in reviewPersonal Retrospective Activity: A year in review Generating a timeline of events

I find the timeline a very powerful way to reflect on the year’s events, and to celebrate their significance. I first brainstormed memorable events before I attempted to nest them into the timeline. I the checked my personal and work calendars, realising that the human memory (or maybe it’s just mine!) is quite bad at remembering the order of events.

I found this blog, my twitter stream and my slideshare page useful sources to remember other significant events.

 TimelinePersonal Retrospective Activity: Timeline

Constructing the timeline took the most time of all exercises. Partly because there were lots of significant events for me, and I wanted to appreciate how much had occurred in this year.

4 L’s (Liked, Loved, Lacked, Longed For

I don’t normally use the 4 L’s exercise but figured I would give it a go. It seemed to work well in terms of framing insights but I found I needed to reflect deeper in some of the initial ideas I wrote up. Having an independent coach/facilitator would have been useful but I had to play this role myself.

 4LsPersonal Retrospective Activity: 4Ls Goals for 2016

After looking back at the timeline, and reflecting on how the events made me feel and what impact they had, I brainstormed some goals for this year. My focus for this first round was to generate all possible goals I might have, even though these long term goals would not meet the SMART criteria.

 Goals (Before Actions)Personal Retrospective Activity: Goals (Before Actions)

In the second round, I went through each of the different goals, generating some concrete next steps to move me towards each of those goals. My intention is to revisit the goals throughout the year and to take other actions to progress them further. The orange-coloured stickies in the picture below represet these next steps linked to the relevant goals (in green).

 Goals (Next Step Actions)Personal Retrospective Activity: Goals (Next Step Actions)

I also spent the time digitising the outputs into a A3 Personal Retrospective report and have made the template available here if you want to print it instead.

Have you set aside time to reflect on 2015? How did you run your Personal Retrospective? Leave a comment and let me know.

If you liked this post, you might be interested in The Retrospective Handbook: A guide for agile teams, also available in print.

Categories: Blogs

Scrum Master Resolutions (2016 Edition)

Illustrated Agile - Len Lagestee - Mon, 12/28/2015 - 19:15

It is hard to believe 2015 is almost over and it’s even harder for me to believe that this blog has been around long enough to have a Scrum Master resolution post for the 5th year in a row. In case you’ve missed any of them here are the four earlier New Year resolution posts.


If there is a theme for the resolutions this year it would be “evolving the role.” Having been involved with many organizations as they attempt to improve and transform I am recognizing how much more is required from all roles, but especially Scrum Masters and Agile Coaches.

The call to all of you heading into the new year is to challenge traditional beliefs with what you think is possible with your role and recognize the opportunity you have in becoming a catalyst for change – regardless of how complex or “broken” your organization has become.

Hopefully, the 3 resolutions for 2016 will be enough to get you started on your journey but there will be much more to come from Illustrated Agile throughout the year.

Look harder. Your team, leaders, and organization is revealing important details about what is needed from the role of Scrum Master (and it may not be a fancy framework or a few Agile buzzwords, tools and ceremonies). Observing takes real practice and journaling is an important way to help improve this trait. Check out the note below to see how you can get a worksheet I have used to help Scrum Masters begin to capture their observations about what they are see and sensing. My most commonly used question when coaching a Scrum Master is “What are you sensing?”

Find more time to think. Take what you are observing and carve out quality time to think…just think. Ask yourself challenging questions. Why is this happening? Why is it really happening? What are all my senses telling me about the situation? What is the system telling me?

Last year we resolved to slow down and allow imperfections to emerge. This year, resolve to create time and space to add a dose of critical thinking to your role.

Hopefully, this quote from Leandro Herrero will inspire you (as it did me):

Critical thinking has wonderful unintended consequences: being humble is one. Free from the heavy load and duty of being always right, a burden that the uncritical thinker tends to bear, the critical one is agile and nimble.

Increase bravery. You’ve sensed what the system is telling you. You’ve given yourself the space to pause and think. Now it’s time to strengthen your resolve to become a catalyst for change. Be vocal. Be a friend. Be a spark. Be a raging fire. Be encouraging. Be strong. Be open to new possibilities. Everyday, ask how you can instigate change in your company culture…otherwise, the culture is slowly changing you.

Have an awesome 2016 everyone! Be brave. Len

For a limited time, get a digital copy of the book “Becoming a Catalyst: Scrum Master Edition” for free when you subscribe to the blog. You will also receive the Becoming a Catalyst Companion Worksheet to help develop the 8 traits of a Catalyst Scrum Master explained in the book.

Becoming a Catalyst - Scrum Master Edition

The post Scrum Master Resolutions (2016 Edition) appeared first on Illustrated Agile.

Categories: Blogs

R: Error in approxfun(x.values.1, y.values.1, method = “constant”, f = 1, : zero non-NA points

Mark Needham - Sun, 12/27/2015 - 14:24

I’ve been following Michy Alice’s logistic regression tutorial to create an attendance model for London dev meetups and ran into an interesting problem while doing so.

Our dataset has a class imbalance i.e. most people RSVP ‘no’ to events which can lead to misleading accuracy score where predicting ‘no’ every time would lead to supposed high accuracy.

Source: local data frame [2 x 2]
  attended     n
     (dbl) (int)
1        0  1541
2        1    53

I sampled the data using caret‘s upSample function to avoid this:

attended = as.factor((df %>% dplyr::select(attended))$attended)
upSampledDf = upSample(df %>% dplyr::select(-attended), attended)
upSampledDf$attended = as.numeric(as.character(upSampledDf$Class))

I then trained a logistic regression model but when I tried to plot the area under the curve I ran into trouble:

p <- predict(model, newdata=test, type="response")
pr <- prediction(p, test$attended)
prf <- performance(pr, measure = "tpr", x.measure = "fpr")
Error in approxfun(x.values.1, y.values.1, method = "constant", f = 1,  : 
  zero non-NA points

I don’t have any NA values in my data frame so this message was a bit confusing to start with. As usual Stack Overflow came to the rescue with the suggestion that I was probably missing positive/negative values for the independent variable i.e. ‘approved’.

A quick count on the test data frame using dplyr confirmed my mistake:

> test %>% count(attended)
Source: local data frame [1 x 2]
  attended     n
     (dbl) (int)
1        1   582

I’ll have to randomly sort the data frame and then reassign my training and test data frames to work around it.

Categories: Blogs

20 PMI-ACP v2 Sample Questions

Leading Answers - Mike Griffiths - Thu, 12/24/2015 - 03:53
Following the update to the PMI-ACP Exam with the addition of the new “Agile Principles and Mindeset” domain I updated my PMI-ACP Exam Prep book and have now just finished the new questions for FASTrack Exam simulator. Feedback from people... Mike Griffiths
Categories: Blogs

SAFe in Government: Major Contract Awarded to SAI Gold Partner for SAFe Implementation

Agile Product Owner - Thu, 12/24/2015 - 00:25

safe_in_governmentThe Administrative Office of the U.S. Federal Courts awarded Scaled Agile Gold Partner SRA International a five-year contract valued at $115 million. SRA will provide full software development lifecycle expertise for a variety of applications supporting probation and pre-trial services, as well as Case Management/Electronic Case Files which is the system that manages the electronic court filings.

It is gratifying to see the progress that Agile and SAFe are making in the government space (see last post). After all, these are our tax dollars being spent. And as Lean thinking drives elimination of waste, the government is a target-rich environment, as they say on the beltway.

You can read the full press release here, but for anyone monitoring the progress of SAFe in the government, this is the interesting part:

“As part of the program, CSRA will continue to support the CMSO as it transitions all application development to Agile methodologies leading to the implementation of the Scaled Agile Framework® (SAFe®) and Development/Operations (DevOps) methodologies.”

Note: SRA is a subdivision of CSRA.

Happy Holidays everyone!
—Dean and the SAI team



Categories: Blogs

SAFe in Government: Major Contract Awarded to SAI Gold Partner for SAFe Implementation

Agile Product Owner - Wed, 12/23/2015 - 18:40

safe_in_governmentThe Administrative Office of the U.S. Federal Courts awarded Scaled Agile Gold Partner SRA International a five-year contract valued at $115 million. SRA will provide full software development lifecycle expertise for a variety of applications supporting probation and pre-trial services, as well as Case Management/Electronic Case Files which is the system that manages the electronic court filings.

It is gratifying to see the progress that Agile and SAFe are making in the government space (see last post). After all, these are our tax dollars being spent. And as Lean thinking drives elimination of waste, the government is a target-rich environment, as they say on the beltway.

You can read the full press release here, but for anyone monitoring the progress of SAFe in the government, this is the interesting part:

“As part of the program, CSRA will continue to support the CMSO as it transitions all application development to Agile methodologies leading to the implementation of the Scaled Agile Framework® (SAFe®) and Development/Operations (DevOps) methodologies.”

Note: SRA is a subdivision of CSRA.

Happy Holidays everyone!
—Dean and the SAI team



Categories: Blogs

Stop Doing Scrum and Start Being Agile

TV Agile - Wed, 12/23/2015 - 18:00
Learn you should stop trying to implement a methodology from a book in just one team and instead try to create an Agile methodology for your company as a whole. This video discusses the history of Agile and the ideas behind it. You will learn how you can enlighten your company about the advantages of […]
Categories: Blogs

Aanbevolen boeken over agile

Ben Linders - Wed, 12/23/2015 - 13:18

Banner Aanbevolen boeken Ben Linders textBen je op zoek naar een goed praktische boek over agile software ontwikkeling met b.v. Scrum, Kanban of Lean? Of naar een bruikbaar boek over leiderschap of verandermanagement? Op vindt je mijn boek aanbevelingen.

Alhoewel steeds meer informatie beschikbaar is op websites, in blogs en in communities en discussiepagina’s, spelen boeken nog steeds een belangrijke rol. In boeken wordt vaak dieper ingegaan op de materie, wat belangrijk is als je het toe … Continue reading →

Categories: Blogs

Taking Requests for New Edition of Manage Your Project Portfolio

Johanna Rothman - Tue, 12/22/2015 - 17:37

Manage Your Project PortfolioI am about to update Manage Your Project Portfolio: Increase Your Capacity and Finish More Projects to a second edition.

What would you like me to add? To remove? To change? What have your challenges been about project portfolio management?

Here are things I’m planning to add:

  • Many more kanban views of the project portfolio and some words about visualization.
  • Discussion (or more than one) about Cost of Delay.
  • How a project’s product backlog is not the same as an organization’s project portfolio.
  • More discussion about what you optimize and why.

What else would you like to see? Please either comment or send me email. Thanks!

Categories: Blogs