First, there's an important difference between "let" and all the others. "let" defines a
class variable, which has only one instance no matter how many instances of the class are created. All the others define a property that can be set individually on each class instance.
Regarding the choice between the remaining constructs, each of them has different properties so you want to pick the one whose properties match what you need to do. "field" is the most basic and efficient construct, since it just defines a slot in each class instance that can be set to a value. However, there is no way for the class instance to be notified when the value changes, and there is no way that subclasses can modify the field definition. Getter/setter pairs (or
accessors as we call them) are like "virtual fields" -- you can read and write the virtual value using the same syntax that you'd use for reading or writing a field, but the read and write operations are implemented by code that you write. This code can be overridden in a subclass definition, just like a method definition can be overridden. Therefore, with getters and setters, you can get notifications when a value is set, and you can customize the processing when you define a subclass, but since a getter or setter call is effectively a method call, it is more expensive than just reading or writing a field. So accessors are good to use when you need notification that a value has been changed or when the value to be read is expensive to compute and you prefer to wait until the value is actually read before paying the price to compute it. Another point about fields and accessors is that they can be used in any class definition.
Local and nonlocal options, by contrast, can only be used on graphical objects. (Effectively, a class has to be a subclass of Visual if you want to define options on it.) Options also provide a way of getting notifications when an option is set, and you can add additional notification processing when you define a subclass. Also, an option can be
unset, in which case a read operation on the option will just return a default value. When an option is unset, it does not take up any space in the class instance, making it more space-efficient than a field if there will be many class instances in which the option is unset. However, options are more expensive to read and write than fields are, because a run-time search of a linked list is required. Another important thing about options is that you can use keyword arguments in the constructor of a graphical object to initialize option values when the object is created: for example, you can write
{HBox background = "green"} because "background" is an option. You get this capability automatically just by defining an option, but you don't get it for fields or accessors. However, options don't provide a way to compute the value that is read, like getters do. The value that you read for an option is just the value that was set (or the default value of the option if the option is unset).
Nonlocal options are special in that they apply not only to the graphical object that they are set on, but also to descendant objects of that object in the graphical hierarchy. In the basic Curl graphical API, we define options like "color" as nonlocal options so that you can set the "color" option just once on an HBox (for example) and it will automatically affect the color of all objects inside the HBox. On the other hand, local options just affect the object on which they are directly set, so in this way local options are much more like fields and accessors. In the basic Curl graphical API, local options are used for properties that should only apply to one object. For example, when you set the border width on an HBox, you probably don't want to also create a border of the same width for every object inside the HBox, so for that reason border-width is defined as a local option. When you define your own options, you need to think about whether the nonlocal or local behavior will be the most convenient for users of the API that you are designing, and choose the kind of option accordingly.
-Bert