File: Existentials.md

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (10 lines) | stat: -rw-r--r-- 1,456 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
# When to use protocols in SwiftSyntax

Learn when to use protocols value types like ``ExprSyntax`` over protocols like ``ExprSyntaxProtocol``. 


SwiftSyntax tries to minimize the use of existentials (aka. protocols spelled with `any` or protocols spelled without `some`) wherever possible. This is because when the stored value is more than 3 words (a word is the size of a pointer) large, these existentials store their data on the heap. The data stored inside `RawSyntax` is larger than 3 words and thus every time you pass a value around as a e.g. an `ExprSyntaxProtocol`, a new heap allocation will be made and that data needs to be reference-counted, which causes a very noticeable performance overhead. 

swift-syntax offers two alternatives:
- When passing a single node around, use `some ExprSyntaxProtocol`. This allows the concrete expression node (e.g. an ``IntegerLiteralExprSyntax``) to be passed directly without the need to wrap it in an existential and thus avoid the performance overhead.
- When multiple expression nodes need to be represented that might be of different types, eg. in an array of expressions, use the ``ExprSyntax`` type. ``ExprSyntax`` is a struct and can thus be allocated on the stack. The downside is that specific expression nodes need to explicitly be upcast to `ExprSyntax` (`ExprSyntax(integerLiteral)`) and downcast to more specific types using a custom `as` method (`expr.as(IntegerLiteralExprSyntax.self)`).