Hi Graeme and thanks for the proposal! I think we should be very clear about the objectives here, and very clear about how to write such builders. In particular, in the past, we've explicitly discarded the idea of doing "Scala-like" dynamic in compile static mode, because the types are important. In other words, it should be possible to infer the return type of a method missing call based on the arguments. This is why the markup template engine and your static JSON builder use type checking extensions for this: we wanted the developer to provide us with this information.
Now I reckon writing a TC extension is not easy, and not user friendly. I think we should separate 2 cases: - builders for arbitrary hierarchical structures (markup builder) - builders for known types (configuration pattern) For example, one should know if _any_ method call is allowed, or only some of them. The typical example is what Kotlin does with delegates properties so support elegant static builders. It would be very nice to have such a mechanism, but it only works for the 2d type of builders (delegates properties can be contributed through extensions). For the general case (arbitrary builders), I think your idea works well, but performance and type checking will only be limited. 2016-10-05 19:33 GMT+02:00 Jochen Theodorou <blackd...@gmx.org>: > On 05.10.2016 08:13, Graeme Rocher wrote: > [...] > >> So again let's revisit the benefits of this change: >> >> 1) You can write classes annotated with @CompileStatic and use >> builders without having to compromise the design of your code >> 2) You can get type checking for non-builder methods if concrete types >> are used in methodMissing (example "methodMissing(String, Closure)" >> and type checking for properties if "propertyMissing" is not defined >> 3) You will get better performance and no matter what we do to the >> dynamic side that will stay the same >> 4) Our goal should be that as much code as possible is compileable >> with @CompileStatic and this change helps that >> > > I would appreciate to exclude (1) from the discussion for now. Third party > bias and fears will not lead to a constructive discussion. > > Then for (2)... methodMissing(String, Closure) will not get you anywhere > in terms of type checking. This is for methods "foo{...}" or "bar{...}", > where bar and foo are the String. If you write foobar instead, there is > nothing preventing compilation and failure at runtime. And it does not > scale: The more methodMissing you have, the less likely there is the chance > for a compilation error due to builder method argument. And I actually > still fail to see how you want to use this with @DelegateTo(Map), unless > all builder methods of that form will have these properties. > > (3) depends on the implementation. Your suggestion will not give the best > performance, neither in the static, nor in the dynamic world. Which really > makes it difficult for me to see the performance argument. You are right in > that using something like categories will make performance degrade of > course. > > And (4)... looks more like a result of (1) to me and will not help > discussion.. Unless you say you only want a builder that will pass static > compilation and don´t care about real type checking and performance. In > that case we can shorten this discussion a lot. > > > bye Jochen >