Exit Full View

Feather2 / documentation / DataAnnotation.md

Data Annotation

I'm trying out a language feature that isn't available in Java or Kotlin.

Immutable classes are good, because they have no side effects, and therefore bugs are much less likely. However, if you have a data structure with many properties, it is tempting to make the data structure mutable.

Suppose we need to model a bolt (machine screw) :

class Bolt(
    val diameter : double,
    val length : double,
    val pitch : double,
    val headDiameter : double,
    val headHeight : double
) {        
    meth volume() = x * y * z
}

val m6Bolt = Bolt( 6.0, 40.0, 1.0, 12.0, 4.0 )

Now suppose we want a longer one, with all other attributes the same. We could write this method :

meth length( length : double ) = Bolt( diameter, newLength, pitch, headDiameter, headHeight )   

val longerBolt = m6Bolt.length( 80.0 )

We could create similar methods for all other attributes too.

meth diameter( diameter : double )         = Bolt( diameter, newLength, pitch, headDiameter, headHeight )   
meth pitch( length : double )              = Bolt( diameter, newLength, pitch, headDiameter, headHeight )   
meth headDiameter( headDiameter : double ) = Bolt( diameter, newLength, pitch, headDiameter, headHeight )   
meth headHeight( headHeight : double )     = Bolt( diameter, newLength, pitch, headDiameter, headHeight )   

But there are some problems.

  • It isn't clear that we have all the parameters in the correct order.
  • We end up writing 5 methods, which all look identical apart from the names.
  • Adding a new attribute to the class is a PITA, because all these methods need updating.

So instead, add the annotation @Data to the fields declared in the constructor, and let Feather do the rest :

class Bolt(
    @Data
    val diameter : double,

    @Data
    val length : double,

    @Data
    val pitch : double,

    @Data
    val headDiameter : double,

    @Data
    val headHeight : double
) {        
    meth volume() = x * y * z
}

The 5 methods, diameter(double), length(double), pitch(double), headDiameter(double), and headHeight(double) are auto-generated.

FYI, This is a cut-down version of a real world feather script within my FooCAD application. It was written using Feather version 1, and I'm eager to upgrade it to version 2, so I can get rid of the cruft!