I've been using the proposed feature in SwiftUI since it was introduced last year. But I'm only now digging into the mechanism being proposed.
Overall my experience with the feature has been positive. However, I am a very strong -1 on the name of the attribute.
I believe the attribute name @âfunctionBuilder is very misleading and immediately gives someone new to the feature an incorrect mental model of what the feature does and how it works.
This feature proposal introduces one attribute and seven methods, but the largest API surface area related to this feature will be the names of types that implement this feature in a wide variety of frameworks. So, I think it makes sense to talk about the naming of the attribute and its related methods in that context.
A strong naming convention for these types is already evident among the projects mentioned in the proposal and in examples used in the proposal:
SwiftUI: ViewBuilder, SceneBuilder, CommandsBuilder, ToolbarItemsBuilder
swift-shortcuts: ShortcutBuilder
swift-css: StylesheetBuilder, CSSBuilder
Proposal examples: TupleBuilder and HTMLBuilder.
This naming convention evokes the classic Builder design pattern as a type that builds instances of another type.
I support this naming convention because it seems natural, straightforward, and easy to understand. A ViewBuilder builds views. A ShortcutBuilder builds shortcuts.
Of course, it would naturally follow that a function builder builds functions.
Well, no. A function builder doesn't do that at all.
Based on the description of the feature, the only way I can wrap my head around the name @âfunctionBuilder and have it make sense is the following:
A âfunction builderâ is something that takes the body of a function and transforms it using a transformation known as âbuildingâ. So a function builder is something that acts upon they body of a function to perform something called building on it.
I don't know if that is the correct rationale for the proposed name, but it is the only interpretation I can think of that makes some sense to me.
That interpretation is analogous to calling a home builder a âraw material builderâ as someone who takes raw materials and transforms them into a home using a process known as building.
Both are awkward phrases that do not map to how the that phrase is usually parsed and understood by a reader.
So, just in reading the name of the feature or attribute, most will assume a @âfunctionBuilder creates functions and immediately have an incorrect notion of what the feature is and how it works.
More than a function builder
Another issue with the name @âfunctionBuilder is that it performs its transformation on more than just functions. It also performs them on the getters of computed variables and subscripts. (Perhaps those getters are implemented as anonymous functions at a low level, but to most Swift users, functions, variables, and subscripts are distinct things with different rules for declaration and usage.)
In SwiftUI's public API, no function declarations have a function builder attribute, the only declarations with the attribute are for variables. The other common usage in SwiftUI being as parameter attributes on function types. This also seems to be a common pattern in the other projects listed in the proposal.
It raises the question, why does a function builder work on things that aren't functions?
The use of âfunctionâ in the attribute name seems very imprecise, since the builder can transform the body of Swift declarations other than functions, especially since transforming a non-function declaration (var) is one of the most common uses of the feature.
Is it a term of art?
I am not very well versed in classic functional programming terminology. So, I thought function builder might be an existing term of art.
A Google search for function builder largely turns up two types of results:
It does not appear that the term function builder as used in this proposal is an existing term of art. It does seem like the use of the term function builder in this proposal uses a meaning for the phrase that is different from how the phrase is commonly used and understood.
The term builder on its own is a known term of art referring to the Builder design pattern.
Proposed Attribute Name
I propose the attribute name @âreturnValueBuilder.
The name follows the natural naming pattern of its concrete types such as ViewBuilder, SceneBuilder, etc. Its name also answers the question, what does a @âreturnValueBuilder do? It builds return values.
The name accurately and precisely describes what is built by every type with this annotation. The term return value is used extensively and consistently throughout Swift documentation and applies to functions, closures, computed property getters, and subscript getters.
Finally, it retains the term builder which is a well-known design pattern that accurately describes types that implement this feature, but avoids using it in a phrasing that is awkward and unfamiliar to the reader.
Alternatives Considered
@âbuilder is very concise and avoids the need for the attribute to specify a general term for what it builds. My main concern is that it is a very general term that could cause confusion with any other sort of builder-style mechanism that might be introduced in Swift itself or in developer code.
@âresultBuilder is shorter, but less precise. A @âreturnValueBuilder always builds a return value, not just any result.
@âfunctionTransformer has the issue that the bodies of non-functions can be transformed as well. Also, it is a very general term not indicating at all how the function is transformed. For example, it could be something that transforms a function that returns an Int into a function that returns a String.
One point related @âfunctionTransformer is that the name @âreturnValueBuilder doesn't specify how the type builds a return value. But I think it is more important for the attribute to indicate the purpose of the type, what it is, as opposed to its underlying implementation. Similarly, just by reading the name, we know that a @âpropertyWrapper wraps a property. We don't know exactly how to implement one without learning more about the feature.
@âbodyBuilder This one is included because it is difficult for me to resist a pun. It still uses the awkward phrasing of @âfunctionBuilder by referring to what it acts upon, as opposed to what it creates, but it does more accurately reflect that it acts on the body of things other than functions as well.
Proposed Method Names
While I am strongly against the name @âfunctionBuilder and think a better alternative should be adopted, I do not have as strong an opinion about the names of the seven build... methods themselves.
As developers, we often think of 'build' as a noun as well as a verb. (Don't break the build!) So reading a name like 'buildExpression' I sometimes parse it as an expression that has something to do with a build, as opposed to a command to build an expression.
As the discussion regarding method names continues, I'd like to note that a home builder can pour a foundation, frame a house, and rough-in electrical wiring. So, generally speaking, a builder can perform verbs that are more specific or precise than 'build'.
Conclusion
I believe this feature / attribute is an important one in Swift and deserves to have a name that is not immediately misleading and that accurately describes types that adopt this attribute. I don't believe that @âfunctionBuilder meets this standard and propose that @âreturnValueBuilder does.