• Home
  • About
  • The Best Groovy Inspections You’re Not Using

    January 18th, 2012

    Many, many tools perform static analysis on code. There are all sorts of automated ways to look through your code and tell you if there are likely errors or not. FindBugs, PMD, and CheckStyle are some of the big names from the Java world. On the Groovy side we have two real options: IntelliJ IDEA and CodeNarc.

    This post highlights my favorite static analysis rules for Groovy in IDEA that are not enabled by default. Groovy in IDEA 11 has well over 100 rules, but less than half of them are activated when you install the product. To turn these rules on you’ll need to go into Settings (Ctrl+Alt+S) and enable them under Inspections.

    So here are my favorites that I think you should turn on:

    Threading
    Threading comes first because these inspections have saved my butt in the past. None of them are enabled by default, so do yourself a favor and enable a few. These ones are all must haves:

    * Access to static field locked on instance data – Reading and writing a static field from multiple threads is not thread-safe. It needs to be done within a synchronized block. Do you know what happens when you synchronize on instance data, like this:

    class MyClass {
        static resource
        final lock = new Object()
    
        def initialize() {
            synchronized(lock) {
                resource = new Resource()
            }
        }
    }

    The object ‘lock’ is an instance field, not a static field. So this assignment within the synchronized block is not thread-safe. It is possible that the static field is accessed from multiple threads, which can lead to unspecified side effects.

    * Synchronization on non-final field – If you are accessing a variable within a synchronized block then your synchronization token must be final. Consider this code:

    class MyClass {
        def resource
        def lock = new Object()
    
        def initialize() {
            synchronized(lock) {
                resource = new Resource()
            }
        }
    }

    The field ‘lock’ is not final, so different instances of MyClass may have different values for lock. The result is that different threads may be locking on different objects even when operating on the same object. Make your locks final.

    * Synchronization on variable initialized with literal – Do you understand the problem with synchronizing on a primitive literal? Consider this code:

    class MyClass {
        def lock = 'my lock'
    
        def initialize() {
            synchronized(lock) {
                // do something
            }
        }
    }

    Strings are interned by the JVM, so the string ‘my lock’ may also be used by another class. Numbers are even worse because they can be assigned from a cache. Some other object in the system may be initialized with the same literal, and could create an accidental (or malicious) dead-lock situations.

    * Unsynchronized method overrides synchronized method – In some limited circumstances you may actually want to override a synchronized method with an unsynchronized one. But probably not. More than likely you don’t even know and you are accidentally creating a subtle bug. If the parent is synchronized then the child should be also. Or better yet, make the parent final.

    Probably bugs
    * Named arguments of constructor call – This inspection warns you when something like the following happens when using named arguments, which is almost certainly a bug:

    class Order {
         int orderId
    }
    
    new Order(orderid: 5)

    See the problem? The field is named ‘orderId’ with a big ‘I’ and the constructor call uses ‘orderid’ with a small ‘i’. RuntimeException if you run this code. This is a type of bug that CodeNarc cannot find because the type information of the classes is so limited. IDEA keeps track of types much better and can do nice things like this.

    * Access to unresolved expression – There has been a lot of talk over the years about adding static compilation to Groovy. Some people want to be warned by the compiler or in the IDE if their Groovy code is referencing an object that does not exist. For example, they’d like this to produce a warning or error:

    def c = { parm ->
        println it
    }

    See the problem? The closure parameter is named ‘parm’ but the closure references the parameter by the standard name ‘it’. The access to unresolved expression inspection turns this into a warning or error in the IDE. IDEA is quite smart about it too and knows all about delegate/super and the other Groovy dynamic variables. If you like this sort of thing then be sure to read up on Grumpy mode in Groovy 2, coming soon.

    Control Flow
    There are many features in Groovy that simplify standard and verbose Java code. Two of these are the Elvis operator and the Null-Safe Dereference. IDEA contains inspections to help you migrate to the new way of writing code with these features.

    * Conditional expression can be elvis – This inspection migrates you from code like this:

    def x = value != null ? value : 2

    And suggests you rewrite it into the equivalent Groovy:
    def x = value ?: 2

    Is it always safe to make this transformation? (Think about it for a few seconds). GroovyTruth means it is not. Technically speaking, the two code snippets are not equivalent: value != null may be true while value is false, such as when value is an empty String. Overall, I like the inspection but you need to be careful with it.

    * Conditional expression can be conditional call – This inspection promotes the use of the Null-Safe dereference. This following code produces a violation:

    def x = value != null ? value.toString() : null

    … and you will be prompted to transform it ito:
    def x = value?.toString()

    These two code blocks really are the same and this can be safely accepted as the correct way to write the code.

    * If statement (or conditional) with identical branches - I periodically refactor code and accidentally leave an if or conditional statement with identical branches. These are of course redundant and can be cleaned up by removing the if expression. If you have good unit tests and use automated refactorings then this sort of things happens from time to time. The cleanup reminder is nice.

    Error Handling
    * Unused catch parameter - My favorite Error Handling inspection is ‘Unused catch parameter’. Consider this code:

    try {
        doSomething()
    } catch (e) {
        LOG.error('unexpected error occurred')
    }

    What happens to the stack trace in this scenario? It gets eaten up, never to appear in a log. You shouldn’t have any unused catch parameters. If you really don’t care about the exception then name it ‘ignore’ or ‘ignored’ to suppress the warning.

    Validity issues
    * Duplicate switch case – Groovy has Switch on Steroids, meaning you can put almost any object in the case statement, including regular expressions:

    switch (input) {
        case ~/[0-9]/ : println 'numeric!'; break
        case ~/[0-9]/ : println 'a number'; break
    }

    See the problem? The same regex appears twice. The second case will never be executed, even if it would match. As long as your case statements have literals in them then IDEA can verify that there are no duplicates.

    Naming Conventions
    Lastly, there are a whole bunch of naming convention inspections that you can activate and configure. If you’re not using CodeNarc (why not?) then you should at least activate some of these. Standards, on a whole, are good to adhere to.

    IDEA Inspections of CodeNarc?
    So which should you use, IDEA or CodeNarc? These two tools complement each other. There is good reason to use both CodeNarc and IDEA together. CodeNarc does have more inspections than IDEA, but the IDE integration in IDEA is better. Pressing Alt+Enter typically rewrites the offending code, and the speed of the actions are much better in IDEA. Also, the static analysis rules do not overlap between the products because the CodeNarc developers (that’s Chris Mair and myself) already use IDEA and made a conscious effort not to duplicate anything.

    And if you do want to use CodeNarc and IDEA, then you might try out the CodeNarc IDEA plugin.

    If you like this then you might check out some of my other IDEA related posts: The 10 Best Inspections You’re Not Using (in Java), or the IDEA archive on my blog and the Canoo blog.

    And remember if you need Groovy and Grails help, then give us a call or drop me an email at hamlet.darcy@canoo.com


    The Art of Groovy Command Expressions in DSLs

    December 8th, 2011

    Domain Specific Languages (DSLs) are often littered with the accidental complexity of the host language. Have you ever seen a supposedly “friendly” language expression like “ride(minutes(10)).on(bus).towards(Basel)”. The newest version of Groovy contains a language feature that aims to eliminate the noise of all those extra periods and parenthesis, so that your DSL looks more like “ride 10.minutes on bus towards Basel”. This article shows you step-by-step how to use Groovy Command Expressions and plain old metaprogramming to write just this DSL, and also offers advice on when, and when not, to use this new language feature.

    The State of the Art with DSLs

    Domain Specific Languages (DSLs) have been in vogue for a long time, and the topic has featured regularly at No Fluff shows for years now. The value proposition of a DSL rests in the idea that programmers and users benefit from expressing their desires in a language closer to English than to Java, using words suited to the problem domain rather than the programming language. The goal is not to create an entire new language, but to create a small language just big enough for users to capture their commands and intents in a more natural way than is typically possible in code.

    Different languages support DSLs in various ways. Some languages make it easy to write nice, readable natural language-ish code and others do not. Over the next few pages we’ll explore the state of the art with Groovy DSLs, starting with looking at some unimaginative Groovy code, seeing how to convert into a better fluent interface, transforming it further using metaprogramming, and finally showing the full power of Groovy Command Expressions. As a sample problem, imagine trying to specify directions on how to get somewhere. By the end of the article you’ll understand how the Groovy code in Listing 1 works even though to looks almost like plain English sentences.

    stand 7.minutes at busstop
    ride 10.stops on bus towards Basel
    stand 5.minutes at tramstop
    ride 3.stops on tram towards Birsfelden
    Listing 1: A DSL for giving Directions

    The Canvas

    We’ll use the same running example through all of the exercises. So let’s start by painting out a few primitive ideas. Think of these basic building blocks as the undercoat to our DSL canvas. Thinking about your domain is always a good place to start if you’re considering writing a DSL. Think, analyze, and compare the domain to see how it should be naturally organized. If you read the example in Listing 1, you may notice a few similarities between the different lines of code. There are actions, such as ‘stand’ and ‘ride’. There are vehicles, such as a ‘bus’ or a ‘tram’. And there are locations, such as the ‘bus stop’, ‘Basel’, and ‘Birsfelden’. We’ll model the actions as methods later, so let’s skip those for now. Vehicles and Locations are fairly straightforward, so we’ll model those as Java enums, as shown in Listing 2. I’ve put them in a package so that I can do a static import on them later.

    package nfjs
    
    enum Location {
        busstop, Basel, tramstop, Birsfelden
    }
    enum Vehicle {
        bus, tram
    }
    Listing 2: Modeling Locations and Vehicles

    There is also something else in common between all of the instructions from Listing 1. They all have a duration or distance, such as ’7 minutes’ or ’10 stops’. A duration is a little bit harder to model, but not much so. For sake of simplicity, we’ll just define a Duration class that represents either a unit of time or a unit of distance, as shown in Listing 3. I applied the TupleConstructor annotation to generate a set of constructors on the object, making it a little easier to work with.

    @TupleConstructor
    class Duration {
        int value
        String unit
    
        String toString() {
            "$value $unit"
        }
    }
    Listing 3: Modeling a Duration

    The last bit of undercoat to apply to our canvas is the Instruction object itself. Listing 1 creates a list of Instructions behind the scenes, so we’ll need to model those as well. Similar to Duration, it’s a simple data type with a few properties and is shown in Listing 4.

    @TupleConstructor
    class Instruction {
      String action
      Location location
      Duration duration
      Vehicle vehicle
    
      String toString() {
        if (vehicle != null) {
          "$action $duration on $vehicle towards $location"
        } else {
          "$action $duration at $location"
      }
    }
    Listing 4: Modeling an Instruction

    An Instruction has an action (stand or ride), a location (bus stop or Basel), a duration (five minutes or three stops), and optionally a vehicle (a bus or a tram). Now that the undercoat is applied, let’s look at some different ways to construct these Instruction objects.

    Cave Paintings

    The most primitive way to create Instructions is to call the constructors of objects directly. This is hardly a DSL but at least it is an improvement over the Java equivalent. There’s not much here to be proud of, and list literals like [] and the leftShift operator to add list elements is only a slight improvement over the alternative. At least Listing 5 is rather short.

    import static cmdexprs.Location.*
    import static cmdexprs.Vehicle.*
    
    instructions = []
    
    instructions << new Instruction(
        'stand', busstop, new Duration(5, 'minutes') 
    )
    instructions << new Instruction(
        'ride', Basel, new Duration(10, 'stops'), bus
    ) 
    Listing 5: Creating Instructions Explicitly

    The problems with this code sample is that there is a lot of accidental complexity: pieces of the underlying programming language bleed through and obscure the intent. In the first instance, only the words ‘stand bustop 5 minutes’ are essential to the problem of creating instructions. The other 59 of the 79 characters are non-essential complexity. A 25% signal to noise ratio is pretty poor. The classical solution to this problem (in a sense that it can be applied to Java code as well) is to create a fluent interface around Instruction objects so that the end user is shielded from these implementation details.

    Classicism

    A fluent interface is a way to chain method calls together in order to eliminate a lot of the noise associated with configuring data. Fluent interfaces can be created with statically compiled languages as well (like Java) and requires no special metaprogramming facilities in the host language. The trick is to be creative with method return types. Listing 6 shows the result of improving our signal to noise ration after refactoring to a fluent interface.

    stand(minutes(5)).at(busstop)
    ride(minutes(10)).on(bus).towards(Basel)
    Listing 6: A Fluent Interface for Instructions

    This is a big improvement and raises or signal to noise ratio from 25% all the way up to 75%. The only noise left in this example is the parenthesis party nestled between all the interesting bits. Hmmm, looks like someone invited a few periods along as well. We’ll do better in the next example, but let’s look at how to implement this fluent interface first.

    As I said, the trick is to be creative with return types. For example, the code ‘minutes(5)’ actually instantiates a Duration object for us (Listing 7), which is then passed into the ‘stand’ method as an argument.

    def minutes(int length) { 
        new Duration(length, 'minutes') 
    } 
    Listing 7: A minutes Method

    The trick is to make all of the method calls chain together. So the ‘stand’ method needs to return something that has an ‘at’ method on it, and that in turn needs to accept a Location parameter and create the actual Instruction. Technically speaking, stand is a higher-order function: it is a method that returns to you a method. Groovy’s dynamic typing and map-implemented interfaces make this a pretty simple task, as shown in Listing 8.

    def stand(Duration duration) {     
      [at: { Location loc ->
        instructions << new Instruction('stand', loc, duration)
      }]
    }
    Listing 8: The stand Method returns another Method

    In Groovy, an object can be created as a Map literal using the [key: value] syntax. If the keys are Strings and the values or Closures, then that object can be treated as an object and have methods invoked on it, which is what Listing 8 shows.

    At first, fluent interfaces often seem complex to implement. But after writing one or two you’ll often find it is really not too difficult. You have to think differently about how you craft an API, but in the end you can get a lot of usage and nice APIs using a fluent interface instead of metaprogramming. Let’s turn now towards bouncing some of those pesky parentheses out of the party using a little Groovy metaClass magic.

    Impressionism

    In our tour of DSL art, I’m calling the next technique impressionism. Like impressionist paintings, it does a slightly better job of capturing the intent than the previous example, but if you examine it closely it doesn’t seem to be much clearer than the alternatives. The motivating code is in Listing 9, can you spot the difference?

    stand(5.minutes).at(busstop)
    ride(10.stops).on(bus).towards(Basel)
    Listing 9: Five Minutes not Minutes Five

    There are two less parentheses, but an added period. ‘minutes(5)’ became ’5.minutes’. The signal to noise ratio improvement is marginal; the advantage here is that the code more closely resembles the away we speak. Nobody sticks their head over the cube wall at 12:05 and asks, “Do you want to go to lunch in minutes 5?” Instead, they say “5 minutes”, which is exactly what this code says. This is a small change to implement, and listing 10 shows that making the language support singular and plural words is just a few lines of code.

    Integer.metaClass.getMinute  = { new Duration(delegate, 'minute') }
    Integer.metaClass.getMinutes = { new Duration(delegate, 'minutes') }
    Integer.metaClass.getStop    = { new Duration(delegate, 'stop') }
    Integer.metaClass.getStops   = { new Duration(delegate, 'stops') }
    Listing 10: Metaprogramming the Duration

    What’s happening here is that we’re adding a method called ‘minutes’ and ‘minute’ onto the Integer class, and this method is creating the Duration object for us. Other than replacing the old ‘minutes()’ method with these four lines of code, there is no change to the previous example. The code all just stays the same.

    The combination of fluent interface and metaprogramming is powerful. Sure, there are some issues with periods and parentheses, but overall it is a pretty big improvement over trying to call constructors and wire objects together in Java. Groovy 1.8 takes things a little bit further and leaves us with the best example yet.

    Expressionism

    The last example is the best. It contains a minimum of accidental complexity and Groovy bleed-through and looks almost like the English language equivalent. For fun, I encourage you to compare Listing 11 with the cave paintings listing in Listing 5. It’s quite a bit improved.

    stand 7.minutes at busstop
    ride 10.stops on bus towards Basel
    Listing 11: Command Expressions

    I call this final version Expressionism, not because it relates very well to the 20th century art movement of the same name, but because it uses a new feature called Command Expressions and is the most expressive of all the examples.

    So what are the code changes? You might notice that there are no more listings in this article. That’s right, command expressions are just the way code may be written now. Listing 11 showing the command expression usage and Listing 9 without the usage are functionally equivalent. ‘Stand’ and ‘ride’ are still method calls that return the ‘at’ and ‘on’ methods. As long as the code follows the follows the pattern ‘method parameter method parameter method parameter’ then it gets converted into ‘method(parameter).method(parameter).method(parameter)’. You can chain as many together as you like; Groovy won’t complain. The result is a nice readable chain of expressions without any additional effort. At the time being, Command Expressions are the state of the art when it comes to DSLs in Groovy.

    Art Criticism

    There are a couple of pitfalls to be wary of. Command expressions are shown here in the best possible light in order to display their power. In reality, they are also a little fragile. Any code not following the ‘method parameter method parameter’ rhythm doesn’t easily fit into the command expression pattern. The result is that you might have to twist your words a little to make them fit into this pattern, which moves it away from natural language and towards accidental complexity. Also, there is always the Groovy grammar and keywords to look out for. For instance ‘for’, ‘native’, and other keywords cannot appear in your DSL, a problem which other languages do have solutions for.

    Also, it is probably best to avoid command expressions outside of DSLs. The code ‘list.collect{ … } each { … }’ looks like a syntax error to most Groovy programmers because there is a period missing before the each method call. However, it isn’t wrong and works just fine. Confusing, but correctly functioning. Currently, Groovy programmers are used to some parentheses and periods, and it’s confusing to leave them out unless you have good reason.

    Create Your Own Art

    Thus concludes the tour of the state of the art with Groovy DSLs. To start, Groovy fluent interfaces are a great way to organize an API and make it easy to use. While not a true domain specific language, in a low ceremony language like Groovy they can go a long way towards increased expressiveness and better signal to noise ration without resorting to programming trickery. For more power, start to use metaprogramming to fine tune the the exact API you need, and use Groovy Command Expressions when you need them. How go forth and make your next DSL a true work of art.

    Need help with Groovy? Canoo is ready to tackle any challenge. Contact info@canoo.com to learn more about Groovy Training and Consulting.


    JavaOne 2011 Thursday and wrap-up

    October 7th, 2011
    Opinions expressed in the post are solely my own and not necessarily those of my employer.

    Thursday started with the Community Keynote. Well, it actually started with a 25 minutes IBM presentation about their cloud story. This had obviously nothing to do with the topic of the event and later speakers pointed this out rather frankly. At least it was interesting to hear that there is a job title like “Cloud Architect”.
    The real part of the Community Keynote started with a quiet moment to honor Steve Jobs.
    Later on, various winners of the Duke choice award and JUG luminaries cared for a lighter mood again, presented their work and asked the audience for participation in their local JUGs and in the advancement of Java via the OpendJDK. The JavaPosse appeared on stage and presented a funny show.
    It was also announced that many of the JavaOne talks will be available on parleys.com, which provide by far the best experience when it comes to viewing live-captured talks.
    Afterwards I attended the ZeroTurnaround (JRebel) talk on classloader issues. The rather big room (~300 ppl) was packed and left the impression that many Java developers share a common pain around classloaders. It was a good talk, covering the basics and typical pifalls. The only surprise for me was *how* easily you can end up with a classloader leak.
    In order to improve my fathering skills, I went into Ken Sipe’s talk on “Rocking the Gradle”, where I met Adam Bien. Ken is a great presenter. However, convincing the crowd is a challenge especially as many Maven users seem to suffer from the Stockholm syndrome.
    Then onto “Visualization of Geomaps and Topic Maps with JavaFX 2.0″, which had some interesting visuals captured here.
    For me JavaOne 2011 finished with Jim Clarke and Dean Iverson on GroovyFX, where they made some really good points suggesting that Groovy is the best language to drive the JavaFX 2.0 API.
    As a side note, James Weaver introduced me to Jim Clarke by pointing out “He is from *Canoo*”. Then the discussion went into how well-known Canoo is in the community and that all employees must be true geniuses to achieve so much with so few people :-)
    Fazit: Still, JavaOne is nowhere near where it was before the Oracle acquisition both in terms of size and in terms of being an unparalleled community experience. Distribution all over various hotels just doesn’t feel right. However, meeting friends has been and still remains the most important part of JavaOne and the conference still delivers on that account.
    Important topics were new Java versions, JavaEE (+cloud), and Java for the Desktop with 50+ talks on JavaFX. Whenever the audience was asked about which alternative languages they use, Groovy was the clear winner. It appears that in the mainstream, Groovy has become the default choice for dynamic programming on the JVM.
    The topic of concurrent programming was in my eyes underrepresented. Guillaume and myself had simple usage of GPars in our demos but for such a big and increasingly important topic the coverage should be much more extensive.
    Finally, some visual impressions.
    Good-bye SF
    Dierk Koenig


    JavaOne 2011 Wednesday

    October 6th, 2011

    Opinions expressed in this post are totally my own and not necessarily that of my employer.

    Wednesday started with the infamous “scriptbowl”, a competition between various scripting languages. This year the contenters were JRuby, Groovy, Scala, and Clojure. I wondered whether Scala considers itself a scripting language but obviously they either do or just seek the opportunity to be on stage.

    To keep a long story short: Groovy has won this event for the third time in a row! This year the race was tied with Scala. Guillaume presented Groovy in the typical Groovy-idomatic style and explained every single line of his concurrent visual analyzer for Google+ postings. Dick Wall presented only non-idomatic Scala code. I interpret this as: to make Scala appealing you have to make it look like Groovy. Furthermore, he presented Kojo, which is a great interactive learning environment written in Play/Scala. In contrast to all other presentations, this was not specifically created for the scriptbowl, nor was it written by the presenter, nor was it clear how much effort went into it, nor did the audience see a single line the implementation code. How much this skewed the comparison, I leave to everybody’s judgement. The show was good, though.

    I felt a bit sorry for Clojure. It is a great language and deserves a presentation that is more visually appealing to convince the crowd.

    Afterwards, I attended a hands-on lab for “rapid enterprise development with netbeans”, which was essentially creating a Swing app for database CRUD actions. If I remember correctly, I did the exact same task 1997 with JBuilder. It left me with the feeling of “Yes, it works” but it is not less complex than it was 13 years ago.

    Early afternoon Gerrit Grunwald (better known as @hansolo_) presented his work on simplified custom components for Swing. Given that he speaks about an activity that is both utterly important and highly underadvertised he would really deserve speaking at the center stage.

    Graeme Rocher’s great session about Grails, polyglot datastores (hibernate, jpa, redis, mongodb, …), and the cloud was overshadowed by the news that Steve Jobs has died. Accidentally, the demo application was about showing a BBC News stream, which displayed this information live on stage. Both the presenter and the audience were equally touched.

    The day officially ended with a big event at treasure island. I decided to not go there, though, and meet the former Canooey Denis Antonioli in Berkely where we had a great evening.

    Dierk Koenig


    JavaOne 2011 Tuesday

    October 5th, 2011
    The Java strategy keynote started slowly with Juniper networks presenting their
    take on Java, which was in my eyes not really related to the topic of the keynote.
    It then went on into the Java roadmap with the announcement that new Java versions
    should come every two years, which sounded to me like an excuse for Java 8 being
    deferred until “Summer 2013″.
    The real surprise was a demonstration of JavaFX running various devices like
    tablets and smartphones running Windows, Android, and even iOS! It appeard to
    be experimental but the sheer possibility makes a difference.
    In addition, JavaFX will be fully open-source such that everybody is free to
    port it to his platform of choice.
    Over lunch, the “Java Desktop Community” assembled in a nearby restaurant.
    That was an awesome opportunity for meeting the Swing and JavaFX luminaries just like in the years before.
    In the early afternoon, I headed for the talk about custom JavaFX components
    presented by Jonathan Giles and Jasper Potts. It appears customizing any
    control is mainly done via CSS. In other words, there is no typesafe API.
    I would rather prefer to use CSS only for “skinning” and keeping an API for
    source-code integration.
    It also came out that the current JavaFX version doesn’t contain e.g. a
    ComboBox. This came as a surprise since I would expect this as being part
    of the standard widget set. I curious what else is missing.
    There also is a distinction between public and private APIs that didn’t
    make immediate sense to me – other than the private parts are not yet
    finished.
    The afternoon JavaPosse BOF was rather disappointing. They re-told the
    story of this morning’s keynote. Who needs that?
    Visiting the pavillion was nice even though it was just as small as
    last year. Anyway, I ran into a number of friends and dropped by the
    gradleware booth. They liked my animated Gradle logo, that I implemented
    with the Groovy-based FXG interpreter.
    The SpringSource friends were just shutting down the booth and invited
    me to dinner: http://t.co/LfxhjIH8 . Thanks a lot!

    Finally, late in the evening I joined Dan Sline’s talk on WebServices in the Groovy space. The major take-away for me was a repercussion of the well-known advice: “keep it simple”.

    Throughout the day, a lot of people approached me to tell how much they liked my talks yesterday. That was a really nice experience. Last year I had the very last talk of the conference and only this year I recognized how much of a difference the scheduling of the talks make.

    Dierk Koenig