Problem
_frame.mojo contains five nearly-identical functions (lines 1316–1457):
_from_records_build_null_col
_from_records_build_string_col
_from_records_build_float_col
_from_records_build_int_col
_from_records_build_bool_col
All follow the same template:
- Allocate typed output list +
NullMask
- Loop over
vals: List[DFScalar]
- For each value: if null → append sentinel +
append_null(); else coerce to target type + append_valid()
- Build
Column from typed list + dtype
- Attach null mask and return
Only the target type, default sentinel value, and coercion logic differ between them.
Fix
Now that the visitor pattern is being retired (#747), these can be unified as direct isa[]() dispatch helpers or via a small parametric template. The type-inference call site at line 1800 already handles the "which builder to call" decision — the builders themselves should collapse to one implementation.
~130 lines → ~30.
Problem
_frame.mojocontains five nearly-identical functions (lines 1316–1457):_from_records_build_null_col_from_records_build_string_col_from_records_build_float_col_from_records_build_int_col_from_records_build_bool_colAll follow the same template:
NullMaskvals: List[DFScalar]append_null(); else coerce to target type +append_valid()Columnfrom typed list + dtypeOnly the target type, default sentinel value, and coercion logic differ between them.
Fix
Now that the visitor pattern is being retired (#747), these can be unified as direct
isa[]()dispatch helpers or via a small parametric template. The type-inference call site at line 1800 already handles the "which builder to call" decision — the builders themselves should collapse to one implementation.~130 lines → ~30.