On 20.05.2017 18:06, Nick Coghlan wrote:
That's fine for someone that's already comfortable writing those behaviours by hand and just wants to automate the boilerplate away (which is exactly the problem that attrs was written to solve), but it's significantly more problematic once we assume people will be using a feature like this before learning how to write out all the corresponding boilerplate themselves (which is the key additional complication that a language level version of this will have to account for).
That's a good point. At least, Python does a very good job at reducing boilerplate in many cases in the first case.
One usually starts small instead of big.
In this particular API sketch, data_record is just a class decorator factory, and data_field is a declarative helper type for use with that factory, so if you wanted to factor out particular combinations, you'd just write ordinary helper functions.
I might weigh in that decorating classes seems to be a bit awkward. Especially because I know that there are many people and frameworks out there telling you to decorate your classes with their decorators.
If you don't pay enough attention, you end up having something like this:
@nice_decoration(para1, para2) @decorate_somehow @important_decoration(para3) @please_use_me() class MyClass(Mixin2, Mixin1, BaseClass): para4 = 'foo' para5 = 'bar' para6 = 'boo' para7 = 'baz'
So, there's a region with decorations (decorators + params) OUTSIDE the class and there's a region with declarations (mixins + params) INSIDE the class; BOTH doing some sort of configuration of the class.
I honestly cannot tell which API style would be better but it seems we (at least internally) decided for the latter version: "If it belongs to the class, it should be inside the class."
Maybe, Python standard declarative class construction could be an exception because it's the default. But I am not sure. Technically, I think, both approaches can achieve the same result.
Database object-relational-mapping layers like those in SQL Alchemy and Django would be the most famous precursors for this, but there are also things like Django Form definitions, and APIs like JSL (which uses Python classes to declaratively define JSON Schema documents).
For folks already familiar with ORMs, declarative classes are just a matter of making in memory data structures as easy to work with as database backed ones. For folks that aren't familiar with ORMs yet, then declarative classes provide a potentially smoother learning curve, since the "declarative class" aspects can be better separated from the "object-relational mapping" aspects.