0
# CatBoost Spark Macros
1
2
CatBoost Spark Macros provides compile-time macro annotations for automatically generating parameter getter and setter methods in Apache Spark ML components. This library eliminates boilerplate code by transforming parameter field declarations into complete getter/setter method pairs at compile time.
3
4
## Package Information
5
6
- **Package Name**: catboost-spark-macros_2.13
7
- **Package Type**: maven
8
- **Language**: Scala 2.13
9
- **Installation**: Add to your `pom.xml`:
10
```xml
11
<dependency>
12
<groupId>ai.catboost</groupId>
13
<artifactId>catboost-spark-macros_2.13</artifactId>
14
<version>1.2.8</version>
15
</dependency>
16
```
17
18
## Core Imports
19
20
```scala
21
import ai.catboost.spark.params.macros.ParamGetterSetter
22
```
23
24
## Basic Usage
25
26
```scala
27
import ai.catboost.spark.params.macros.ParamGetterSetter
28
import org.apache.spark.ml.param._
29
30
class MySparkMLComponent extends Params {
31
32
// Annotate parameter declarations to auto-generate getters/setters
33
@ParamGetterSetter
34
final val learningRate: DoubleParam = new DoubleParam(this, "learningRate", "Learning rate for training")
35
36
@ParamGetterSetter
37
final val maxDepth: IntParam = new IntParam(this, "maxDepth", "Maximum tree depth")
38
39
@ParamGetterSetter
40
final val features: StringArrayParam = new StringArrayParam(this, "features", "Feature column names")
41
}
42
43
// The macro automatically generates these methods:
44
// def getLearningRate: Double = $(learningRate)
45
// def setLearningRate(value: Double): this.type = set(learningRate, value)
46
// def getMaxDepth: Int = $(maxDepth)
47
// def setMaxDepth(value: Int): this.type = set(maxDepth, value)
48
// def getFeatures: Array[String] = $(features)
49
// def setFeatures(value: Array[String]): this.type = set(features, value)
50
```
51
52
## Capabilities
53
54
### Parameter Macro Annotation
55
56
The `@ParamGetterSetter` annotation automatically transforms parameter field declarations into getter and setter method pairs.
57
58
```scala { .api }
59
@compileTimeOnly("enable macro paradise to expand macro annotations")
60
private[spark] class ParamGetterSetter extends StaticAnnotation
61
```
62
63
**Supported Parameter Types:**
64
65
```scala { .api }
66
// Basic parameter types
67
BooleanParam → Boolean
68
DoubleParam → Double
69
FloatParam → Float
70
IntParam → Int
71
LongParam → Long
72
DurationParam → java.time.Duration
73
74
// Array parameter types
75
DoubleArrayParam → Array[Double]
76
IntArrayParam → Array[Int]
77
StringArrayParam → Array[String]
78
79
// Generic parameter types
80
Param[T] → T
81
EnumParam[T] → T
82
OrderedStringMapParam[T] → java.util.LinkedHashMap[String, T]
83
```
84
85
**Usage Pattern:**
86
87
The annotation must be applied to parameter field declarations following this exact pattern:
88
89
```scala { .api }
90
@ParamGetterSetter
91
final val parameterName: ParameterType = new ParameterType(this, "parameterName", "description")
92
```
93
94
**Generated Methods:**
95
96
For each annotated parameter, the macro generates:
97
98
```scala { .api }
99
// Getter method - returns current parameter value
100
def get{CapitalizedParameterName}: ParameterValueType = $(parameterName)
101
102
// Setter method - sets parameter value and returns this for chaining
103
def set{CapitalizedParameterName}(value: ParameterValueType): this.type = set(parameterName, value)
104
```
105
106
### Macro Implementation
107
108
The macro transformation logic that processes annotated parameter declarations.
109
110
```scala { .api }
111
private[spark] object ParamGetterSetterMacro {
112
/**
113
* Core macro implementation method that transforms parameter declarations
114
* @param c Macro context for compilation
115
* @param annottees Variable arguments representing annotated expressions
116
* @return Transformed code expression with generated getter/setter methods
117
*/
118
def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any]
119
}
120
```
121
122
## Usage Examples
123
124
### Basic Parameter Setup
125
126
```scala
127
import ai.catboost.spark.params.macros.ParamGetterSetter
128
import org.apache.spark.ml.param._
129
130
class CatBoostClassifier extends Params {
131
132
@ParamGetterSetter
133
final val iterations: IntParam = new IntParam(this, "iterations", "Number of boosting iterations")
134
135
@ParamGetterSetter
136
final val learningRate: DoubleParam = new DoubleParam(this, "learningRate", "Learning rate")
137
138
@ParamGetterSetter
139
final val catFeatures: IntArrayParam = new IntArrayParam(this, "catFeatures", "Categorical feature indices")
140
141
// Generated methods are now available:
142
// getIterations: Int, setIterations(value: Int): this.type
143
// getLearningRate: Double, setLearningRate(value: Double): this.type
144
// getCatFeatures: Array[Int], setCatFeatures(value: Array[Int]): this.type
145
}
146
```
147
148
### Method Chaining
149
150
```scala
151
val classifier = new CatBoostClassifier()
152
.setIterations(1000)
153
.setLearningRate(0.1)
154
.setCatFeatures(Array(0, 2, 4))
155
156
// Access parameter values
157
val currentIterations = classifier.getIterations // 1000
158
val currentRate = classifier.getLearningRate // 0.1
159
```
160
161
### Complex Parameter Types
162
163
```scala
164
import ai.catboost.spark.params.macros.ParamGetterSetter
165
import org.apache.spark.ml.param._
166
167
class AdvancedModel extends Params {
168
169
@ParamGetterSetter
170
final val hyperParams: OrderedStringMapParam[Double] =
171
new OrderedStringMapParam(this, "hyperParams", "Hyperparameter configuration")
172
173
@ParamGetterSetter
174
final val enabled: BooleanParam = new BooleanParam(this, "enabled", "Enable advanced features")
175
176
// Generated methods:
177
// getHyperParams: java.util.LinkedHashMap[String, Double]
178
// setHyperParams(value: java.util.LinkedHashMap[String, Double]): this.type
179
// getEnabled: Boolean
180
// setEnabled(value: Boolean): this.type
181
}
182
```
183
184
## Error Handling
185
186
The macro performs compile-time validation and will abort compilation with descriptive error messages for:
187
188
- **Invalid parameter types**: Unsupported parameter types not in the predefined list
189
- **Wrong type parameters**: Generic parameters without exactly one type parameter
190
- **Invalid usage**: Annotation used on non-parameter declarations
191
192
Example compile-time errors:
193
194
```scala
195
// Error: "Bad paramType: CustomParam"
196
@ParamGetterSetter
197
final val custom: CustomParam = new CustomParam(this, "custom", "desc")
198
199
// Error: "Param must have one type parameter"
200
@ParamGetterSetter
201
final val multi: Param[String, Int] = new Param(this, "multi", "desc")
202
203
// Error: "Annotation @ParamGetterSetter can be used only with Param declarations"
204
@ParamGetterSetter
205
val notAParam: String = "invalid"
206
```
207
208
## Dependencies
209
210
The macro requires the following Scala dependencies:
211
212
- `scala.annotation.{StaticAnnotation, compileTimeOnly}`
213
- `scala.language.experimental.macros`
214
- `scala.reflect.macros.whitebox`
215
216
## Compilation Requirements
217
218
- **Macro Paradise**: Requires macro paradise plugin or Scala 2.13+ for macro annotation support
219
- **Compilation Order**: Must be compiled before dependent code that uses the generated methods
220
- **Runtime Removal**: Uses `@compileTimeOnly` to ensure the annotation is removed from runtime bytecode