Skip to content

SY-3482: Add Boolean Support to Arc#2230

Open
emilbon99 wants to merge 3 commits intosy-3272-add-boolean-data-type-channelfrom
sy-3482-add-boolean-support-to-arc
Open

SY-3482: Add Boolean Support to Arc#2230
emilbon99 wants to merge 3 commits intosy-3272-add-boolean-data-type-channelfrom
sy-3482-add-boolean-support-to-arc

Conversation

@emilbon99
Copy link
Copy Markdown
Contributor

@emilbon99 emilbon99 commented Apr 17, 2026

Issue Pull Request

Linear Issue

SY-3482

Description

Introduces a dedicated bool kind in the Arc type system rather than overloading u8 for boolean signals. Comparisons (==, !=, <, >, <=, >=), logical operators (and, or, not), and string equality now return bool; stage activation, select, set_authority, stat.reset, channel.write, time.interval, and time.wait inputs/outputs are typed bool; numeric literals assign to bool via implicit normalization (nonzero → 1) and bool(x) casts normalize runtime numeric values to canonical 0/1 via double-eqz (integers) or != 0 (floats).

Adds op.AndBool / op.OrBool / op.NotBool (logical NOT, not bitwise), channel and series bool host functions in both Go and C++ runtimes, and routes comparison results through BOOL_T series at the telem layer so the data type tag matches the Arc-level type. The ArcLexer grammar picks up a bool keyword; analyzer, compiler, and constraint unification all understand bool as a distinct non-numeric primitive with bidirectional casts to every numeric type.

Breaking change for Arc programs: channels that previously used u8 as boolean signals (stage triggers, reset lines, activation sources) must now be declared bool. Functions returning comparisons must declare bool return type instead of u8.

Basic Readiness

  • I have performed a self-review of my code.
  • I have added relevant, automated tests to cover the changes.
  • I have updated documentation to reflect the changes.

Greptile Summary

This PR introduces bool as a first-class type in Arc's type system, distinct from u8. Comparisons, logical operators, stage triggers, and channel operations now return or accept bool; bidirectional casts to/from all numeric types are provided via double-eqz (int) or != 0 (float) normalization. The change touches the parser, type-checker, compiler, Go/C++ WASM runtimes, telem op layer, and the TypeScript codec (which gains bit-packing for bool series on the wire).

  • P1bindI64Type (line 552) and bindFloatType (line 680) in arc/go/stl/series/series.go still initialize scalar comparison result series with telem.Uint8T instead of telem.BoolT. Every other comparison path (bindCompareScalarI32, bindCompareOps) was updated to BoolT, so comparisons on i64/u64/f32/f64 series against a scalar will return a series tagged as u8 rather than bool.

Confidence Score: 4/5

Safe to merge after fixing the two scalar-comparison DataType lines in arc/go/stl/series/series.go.

The core type-system additions (new KindBool, EmitCast, logical ops, constraint unification, codec) are well-structured. Two P1 lines in bindI64Type and bindFloatType produce Uint8T-tagged series from scalar comparisons on i64/u64/f32/f64 types, which is a clear oversight compared to the consistently correct BoolT usage everywhere else.

arc/go/stl/series/series.go — lines 552 and 680 in bindI64Type and bindFloatType scalar comparison loops.

Important Files Changed

Filename Overview
arc/go/stl/series/series.go Scalar comparison result DataType is telem.Uint8T in bindI64Type (line 552) and bindFloatType (line 680) — should be telem.BoolT to be consistent with bindCompareScalarI32 and bindCompareOps.
arc/go/types/type.go Adds KindBool support throughout: String(), IsBool(), Density(), Numerics/Booleans slices, FromTelem/ToTelem — all changes look correct.
arc/go/compiler/expression/cast.go Adds emitCastToBool (double-eqz for int, f!=0 for float) and emitCastFromBool; EmitCast early-returns on same-kind and correctly dispatches bool conversions before the generic numeric path.
x/go/telem/op/bool.go Adds AndBool, OrBool, NotBool with correct bitwise shortcuts under canonical 0/1 invariant; hold-last-value semantics for different-length inputs is intentional.
arc/go/compiler/expression/binary.go Comparison/equality expressions now return Bool() instead of U8() for both scalar and series forms — change looks correct.
client/ts/src/framer/codec.ts Adds bit-packing (packBoolBits/unpackBoolBits) for BOOLEAN wire encoding; codec correctly uses density 1 byte/sample in memory but packs 8 samples/byte on the wire.
arc/cpp/stl/series/series.cpp BIND_SERIES_OPS(bool, uint8_t, BOOL_T) adds all operations for bool series in C++ runtime; comparison operators in series.h correctly return BOOL_T. The macro also registers arithmetic ops on bool that the type system prevents at compile time.
arc/go/compiler/expression/logical.go Logical AND/OR now return Bool() — correct change, normalizeBoolean helper is unchanged.
arc/go/stl/op/registry.go Logical ops updated to OrBool/AndBool/NotBool; BoolT added as EqualU8/NotEqualU8 entry for eq/ne since bool bytes are byte-identical to u8 — correct.
arc/go/analyzer/constraints/unify.go IntegerConstant constraint now accepts bool (for b bool := 1 literals), which is required for the implicit-normalization feature described in the PR.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Arc source: x > 5] --> B[Parser / Lexer\nbool keyword added]
    B --> C[Analyzer\ncomparison → Bool type\nIntegerConstant accepts Bool]
    C --> D[Compiler\nbinary.go: returns Bool\nlogical.go: returns Bool\nunary.go: returns Bool\ncast.go: EmitCastToBool / FromBool]
    D --> E[WASM bytecode]
    E --> F{Runtime}
    F --> G[Go runtime\nstl/series/series.go\nbindBool / bindCompareScalarI32 ✓\nbindI64Type scalar ❌ Uint8T\nbindFloatType scalar ❌ Uint8T]
    F --> H[C++ runtime\narc/cpp/stl/series/series.cpp\nBIND_SERIES_OPS bool ✓\nlogical_not ✓]
    G --> I[telem.Series\nDataType: BoolT\nop.AndBool / OrBool / NotBool]
    H --> I
    I --> J[Wire codec\nTS: bit-pack 8 samples/byte\nGo: 1 byte/sample in memory]
Loading

Comments Outside Diff (2)

  1. arc/go/stl/series/series.go, line 552 (link)

    P1 Scalar comparison result for i64/u64 series uses Uint8T instead of BoolT

    bindI64Type's scalar comparison loop initializes the result series with telem.Uint8T, but bindCompareScalarI32 (line 338) and bindCompareOps (series-vs-series, line 411) both correctly use telem.BoolT. Any compare_*_scalar_u64 or compare_*_scalar_i64 host call will return a series whose DataType is u8, contradicting the PR's goal of having all comparison results carry BoolT. Code that inspects series.DataType to determine the Arc type will see u8 instead of bool and may mismatch.

  2. arc/go/stl/series/series.go, line 680 (link)

    P1 Scalar comparison result for f32/f64 series uses Uint8T instead of BoolT

    Same issue as bindI64Type (line 552) — bindFloatType's scalar comparison loop uses telem.Uint8T for the result while series-vs-series comparisons in bindCompareOps (line 411) and the i32-family scalar comparisons in bindCompareScalarI32 (line 338) both use telem.BoolT. Float scalar comparisons (compare_gt_scalar_f32, compare_gt_scalar_f64, etc.) will return series tagged as u8.

Reviews (1): Last reviewed commit: "add copyright headers and pnpm format" | Re-trigger Greptile

Introduces a dedicated Bool kind in the Arc type system rather than
overloading u8 for boolean signals. Comparisons and logical operators
now return bool; stage activation, select, set_authority, stat.reset,
channel.write, time.interval, and time.wait inputs/outputs are typed
bool; numeric literals assign to bool via implicit normalization
(nonzero -> 1) and bool(x) casts normalize runtime numeric values to
canonical 0/1 via double-eqz (integers) or != 0 (floats).

Adds op.AndBool/OrBool/NotBool (logical NOT, not bitwise), channel and
series bool host functions in both Go and C++ runtimes, and routes
comparison results through BOOL_T series at the telem layer so the
data type tag matches the Arc-level type.

Grammar picks up a bool keyword; analyzer, compiler, and constraint
unification all understand bool as a distinct non-numeric primitive
with bidirectional casts to every numeric type.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 80.76923% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.40%. Comparing base (06e1784) to head (224b6cd).
⚠️ Report is 53 commits behind head on sy-3272-add-boolean-data-type-channel.

Files with missing lines Patch % Lines
arc/go/stl/series/series.go 65.62% 19 Missing and 3 partials ⚠️
arc/go/analyzer/types/infer.go 0.00% 3 Missing and 2 partials ⚠️
arc/go/analyzer/expression/expression.go 0.00% 2 Missing and 2 partials ⚠️
arc/go/compiler/expression/cast.go 89.74% 4 Missing ⚠️
arc/go/compiler/expression/unary.go 33.33% 2 Missing ⚠️
arc/go/compiler/resolve/emit.go 0.00% 2 Missing ⚠️
arc/go/runtime/node/state.go 0.00% 2 Missing ⚠️
arc/go/types/type.go 77.77% 2 Missing ⚠️
arc/go/compiler/expression/binary.go 80.00% 1 Missing ⚠️
arc/go/compiler/statement/variable.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                            Coverage Diff                            @@
##           sy-3272-add-boolean-data-type-channel    #2230      +/-   ##
=========================================================================
+ Coverage                                  63.37%   63.40%   +0.02%     
=========================================================================
  Files                                       2106     2107       +1     
  Lines                                     106370   106563     +193     
  Branches                                    8318     8315       -3     
=========================================================================
+ Hits                                       67414    67561     +147     
- Misses                                     33056    33090      +34     
- Partials                                    5900     5912      +12     
Flag Coverage Δ
alamos-go 55.25% <ø> (ø)
arc-go 75.88% <71.69%> (-0.12%) ⬇️
aspen 67.90% <ø> (+0.11%) ⬆️
cesium 82.56% <ø> (-0.05%) ⬇️
client-ts 90.28% <100.00%> (+0.13%) ⬆️
console 20.02% <ø> (ø)
freighter-go 62.91% <ø> (-0.09%) ⬇️
freighter-integration 1.51% <ø> (ø)
freighter-py 79.96% <ø> (ø)
freighter-ts 73.87% <ø> (ø)
oracle 59.53% <ø> (ø)
pluto 55.13% <ø> (+0.02%) ⬆️
x-go 81.74% <100.00%> (+0.18%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant