kumi 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +23 -0
  4. data/CLAUDE.md +7 -231
  5. data/README.md +5 -5
  6. data/docs/SYNTAX.md +66 -0
  7. data/docs/VECTOR_SEMANTICS.md +286 -0
  8. data/docs/features/hierarchical-broadcasting.md +67 -1
  9. data/docs/features/input-declaration-system.md +16 -0
  10. data/docs/features/s-expression-printer.md +2 -2
  11. data/lib/kumi/analyzer.rb +34 -12
  12. data/lib/kumi/compiler.rb +2 -12
  13. data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +157 -64
  14. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +1 -1
  15. data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +47 -0
  16. data/lib/kumi/core/analyzer/passes/input_collector.rb +123 -101
  17. data/lib/kumi/core/analyzer/passes/join_reduce_planning_pass.rb +293 -0
  18. data/lib/kumi/core/analyzer/passes/lower_to_ir_pass.rb +993 -0
  19. data/lib/kumi/core/analyzer/passes/pass_base.rb +2 -2
  20. data/lib/kumi/core/analyzer/passes/scope_resolution_pass.rb +346 -0
  21. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +2 -1
  22. data/lib/kumi/core/analyzer/passes/toposorter.rb +9 -3
  23. data/lib/kumi/core/analyzer/passes/type_checker.rb +3 -3
  24. data/lib/kumi/core/analyzer/passes/type_consistency_checker.rb +2 -2
  25. data/lib/kumi/core/analyzer/passes/{type_inferencer.rb → type_inferencer_pass.rb} +4 -4
  26. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +2 -2
  27. data/lib/kumi/core/analyzer/plans.rb +52 -0
  28. data/lib/kumi/core/analyzer/structs/access_plan.rb +20 -0
  29. data/lib/kumi/core/analyzer/structs/input_meta.rb +29 -0
  30. data/lib/kumi/core/compiler/access_builder.rb +36 -0
  31. data/lib/kumi/core/compiler/access_planner.rb +219 -0
  32. data/lib/kumi/core/compiler/accessors/base.rb +69 -0
  33. data/lib/kumi/core/compiler/accessors/each_indexed_accessor.rb +84 -0
  34. data/lib/kumi/core/compiler/accessors/materialize_accessor.rb +55 -0
  35. data/lib/kumi/core/compiler/accessors/ravel_accessor.rb +73 -0
  36. data/lib/kumi/core/compiler/accessors/read_accessor.rb +41 -0
  37. data/lib/kumi/core/compiler_base.rb +2 -2
  38. data/lib/kumi/core/error_reporter.rb +6 -5
  39. data/lib/kumi/core/errors.rb +4 -0
  40. data/lib/kumi/core/explain.rb +157 -205
  41. data/lib/kumi/core/export/node_builders.rb +2 -2
  42. data/lib/kumi/core/export/node_serializers.rb +1 -1
  43. data/lib/kumi/core/function_registry/collection_functions.rb +21 -10
  44. data/lib/kumi/core/function_registry/conditional_functions.rb +14 -4
  45. data/lib/kumi/core/function_registry/function_builder.rb +142 -55
  46. data/lib/kumi/core/function_registry/logical_functions.rb +5 -5
  47. data/lib/kumi/core/function_registry/stat_functions.rb +2 -2
  48. data/lib/kumi/core/function_registry.rb +126 -108
  49. data/lib/kumi/core/input/validator.rb +1 -1
  50. data/lib/kumi/core/ir/execution_engine/combinators.rb +117 -0
  51. data/lib/kumi/core/ir/execution_engine/interpreter.rb +336 -0
  52. data/lib/kumi/core/ir/execution_engine/values.rb +46 -0
  53. data/lib/kumi/core/ir/execution_engine.rb +50 -0
  54. data/lib/kumi/core/ir.rb +58 -0
  55. data/lib/kumi/core/ruby_parser/build_context.rb +2 -2
  56. data/lib/kumi/core/ruby_parser/declaration_reference_proxy.rb +0 -12
  57. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +36 -15
  58. data/lib/kumi/core/ruby_parser/input_builder.rb +30 -9
  59. data/lib/kumi/core/ruby_parser/parser.rb +1 -1
  60. data/lib/kumi/core/ruby_parser/schema_builder.rb +2 -2
  61. data/lib/kumi/core/ruby_parser/sugar.rb +7 -0
  62. data/lib/kumi/core/types/validator.rb +1 -1
  63. data/lib/kumi/registry.rb +14 -79
  64. data/lib/kumi/runtime/executable.rb +213 -0
  65. data/lib/kumi/schema.rb +14 -3
  66. data/lib/kumi/schema_metadata.rb +2 -2
  67. data/lib/kumi/support/ir_dump.rb +491 -0
  68. data/lib/kumi/support/s_expression_printer.rb +1 -1
  69. data/lib/kumi/syntax/location.rb +5 -0
  70. data/lib/kumi/syntax/node.rb +0 -1
  71. data/lib/kumi/syntax/root.rb +2 -2
  72. data/lib/kumi/version.rb +1 -1
  73. data/lib/kumi.rb +6 -15
  74. metadata +37 -19
  75. data/lib/kumi/core/cascade_executor_builder.rb +0 -132
  76. data/lib/kumi/core/compiled_schema.rb +0 -43
  77. data/lib/kumi/core/compiler/expression_compiler.rb +0 -146
  78. data/lib/kumi/core/compiler/function_invoker.rb +0 -55
  79. data/lib/kumi/core/compiler/path_traversal_compiler.rb +0 -158
  80. data/lib/kumi/core/compiler/reference_compiler.rb +0 -46
  81. data/lib/kumi/core/evaluation_wrapper.rb +0 -40
  82. data/lib/kumi/core/nested_structure_utils.rb +0 -78
  83. data/lib/kumi/core/schema_instance.rb +0 -115
  84. data/lib/kumi/core/vectorized_function_builder.rb +0 -88
  85. data/lib/kumi/js/compiler.rb +0 -878
  86. data/lib/kumi/js/function_registry.rb +0 -333
  87. data/migrate_to_core_iterative.rb +0 -938
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98308b4c27cb40488f14215c8da9700c62a51fc54d11b9d822a1eb25d396a724
4
- data.tar.gz: 3fbbb50dc0c74ba14d83fbcf71c5866efa814b71b4d2679c45b57d59a1f778da
3
+ metadata.gz: dc6d1a550925563fbffcc0f4f96e6609d70734dfff031d9e6e2bfd405ecf45f8
4
+ data.tar.gz: '090999f0550fcd66a79cb3f683b8f27680b5921166267bbdf57dd8c593d3c6fd'
5
5
  SHA512:
6
- metadata.gz: 4453ea76de50c433696c3ae5ebe4d39ae049cb35e40f34cf9a3cce0e52e5d0967a8ccfd9ca7627eafe33444ea4da186015a59796a59e022fdf5b5edc04c50444
7
- data.tar.gz: dfdb9f118ee7c0c16fa30392b3591b88c8320a2d19ff331253a4344e49fa773967e6b8d2451c0fd490f200171846fec2b408ecd000e6ad111e3c2d89bd92c000
6
+ metadata.gz: 9c18d000d924168fbef1abcc6a19f59f18af8a82fae6d4d7bb14e475ce5b34032f031a14ae3d20faa8deadf96f7e1da9bb2190fca0251da74d629c38f637c139
7
+ data.tar.gz: 37f124928afe975bb7138c2856093849b6c15fb23694d77a7a0d1628b2c67f7e262576cb734a522105b8f83253fe112f6cbacc00895ad2daba4212eb7a337384
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ plugins:
4
4
 
5
5
  AllCops:
6
6
  NewCops: enable
7
- TargetRubyVersion: 3.0
7
+ TargetRubyVersion: 3.1
8
8
  SuggestExtensions: false
9
9
  Exclude:
10
10
  - 'bin/*'
data/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ ## [0.0.12] – 2025-08-14
2
+ ### Added
3
+ - Hash objects input declarations with `hash :field do ... end` syntax
4
+ - Complete hash object integration with arrays, nesting, and broadcasting
5
+
6
+ ## [0.0.11] – 2025-08-13
7
+ ### Added
8
+ - Intermediate Representation (IR) and slot-based VM interpreter.
9
+ - Scope-aware vector semantics (alignment, lift, hierarchical indices).
10
+ - Debug tooling: IR dump, VM/lowering traces via DEBUG_* flags.
11
+
12
+ ### Changed
13
+ - Analyzer now lowers to IR via `LowerToIRPass`.
14
+ - Access modes: `:read`, `:ravel`, `:each_indexed`, `:materialize`.
15
+
16
+ ### Removed (BREAKING)
17
+ - JavaScript transpiler (legacy compiler).
18
+
19
+ ### Requirements
20
+ - Ruby >= 3.1 (Was >= 3.0)
21
+
22
+ ### Notes
23
+ - No expected DSL changes for typical schemas; report regressions.
data/CLAUDE.md CHANGED
@@ -18,11 +18,6 @@ Kumi is a Declarative logic and rules engine framework with static analysis for
18
18
  - `bundle exec rspec spec/path/to/specific_spec.rb` - Run specific test file
19
19
  - `bundle exec rspec spec/path/to/specific_spec.rb:123` - Run specific test at line
20
20
 
21
- ### Gem Management
22
- - `bundle install` - Install dependencies
23
- - `gem build kumi.gemspec` - Build the gem
24
- - `gem install ./kumi-*.gem` - Install locally built gem
25
-
26
21
  ## Architecture Overview
27
22
 
28
23
  ### Core Components
@@ -72,50 +67,8 @@ Kumi is a Declarative logic and rules engine framework with static analysis for
72
67
  - Supports custom function registration with type metadata
73
68
  - Each function includes param_types, return_type, arity, and description
74
69
  - Core functions include: `==`, `>`, `<`, `add`, `multiply`, `and`, `or`, `clamp`, etc.
75
- - Maintains backward compatibility with legacy type checking system
76
70
  - Function documents are generated by the script ./scripts/generate_function_docs.rb
77
71
 
78
- **Input Validation System** (`lib/kumi/input/` and `lib/kumi/domain/`):
79
- - `input/validator.rb` - Main validation coordinator for type and domain checking
80
- - `input/type_matcher.rb` - Type validation logic for primitive and complex types
81
- - `input/violation_creator.rb` - Creates standardized violation objects with detailed messages
82
- - `domain/validator.rb` - Domain constraint validation (ranges, arrays, procs)
83
- - `domain/range_analyzer.rb` - Range domain analysis and validation
84
- - `domain/enum_analyzer.rb` - Enumeration domain analysis and validation
85
- - `domain/violation_formatter.rb` - Formats domain violation error messages
86
-
87
- ## DSL Syntax Requirements
88
-
89
- ### Critical Syntax Rules
90
-
91
- **Module Definition Structure**
92
- ```ruby
93
- # CORRECT - CLI can find and load this
94
- module SchemaName
95
- extend Kumi::Schema
96
-
97
- schema do
98
- # schema definition here
99
- end
100
- end
101
- ```
102
-
103
- **Function Call Syntax**:
104
- - **Symbol style**: `fn(:function_name, arg1, arg2, ...)` - The only supported function call syntax
105
-
106
- **Arithmetic Operations**:
107
- - **Sugar Syntax**: `input.field1 + input.field2` - Works for input fields and value references
108
- - **Function Syntax**: `fn(:add, input.field1, input.field2)` - Always works, more explicit
109
- - **Mixed**: Sugar syntax for basic operations, function syntax for complex ones
110
-
111
- **Cascade Condition Syntax**:
112
- ```ruby
113
- value :status do
114
- on trait_name, "Result"
115
- base "Default"
116
- end
117
- ```
118
-
119
72
  ### Key Patterns
120
73
  **DSL Structure**:
121
74
  ```ruby
@@ -133,17 +86,15 @@ schema do
133
86
  string :category
134
87
  end
135
88
 
136
-
137
-
138
89
  # Fields with no declared type
139
90
  any :misc_field
140
91
  end
141
92
 
142
- trait :name, (expression) # Boolean conditions with new syntax
93
+ trait :name, (expression) # Boolean conditions
143
94
  value :name, expression # Computed values
144
95
  value :name do # Conditional logic
145
- on condition, result
146
- base default_result
96
+ on condition, result # on <trait> ?,<trait> , <expr>
97
+ base default_result # base <expr>
147
98
  end
148
99
  end
149
100
  ```
@@ -151,13 +102,6 @@ end
151
102
  **IMPORTANT CASCADE CONDITION SYNTAX:**
152
103
  In cascade expressions (`value :name do ... end`), trait references use bare identifiers:
153
104
 
154
- **Input Block System**:
155
- - **Required**: All schemas must have an `input` block declaring expected fields
156
- - **Type Declarations**: Preferred via type-specific methods (e.g. `integer :field`, `string :name`, `any :field` for untyped fields)
157
- - **Complex Types**: Use helper functions: `array(:element_type)` and `hash(:key_type, :value_type)`
158
- - **Domain Constraints**: Fields can have domains: `integer :age, domain: 18..65` (validated at runtime)
159
- - **Field Access**: Use `input.field_name` to reference input fields in expressions
160
- - **Separation**: Input metadata (types, domains) is separate from business logic
161
105
 
162
106
  **Expression Types**:
163
107
  - `input.field_name` - Access input data with operator methods (>=, <=, >, <, ==, !=)
@@ -179,30 +123,6 @@ In cascade expressions (`value :name do ... end`), trait references use bare ide
179
123
  - Type inference for all declarations based on expression analysis
180
124
  - Type primitives: `:string`, `:integer`, `:float`, `:boolean`, `:any`, `:symbol`, `:regexp`, `:time`, `:date`, `:datetime`
181
125
  - Collection types: `array(:element_type)` and `hash(:key_type, :value_type)` helper functions
182
- - Type compatibility checking and unification algorithms for numeric types
183
- - Enhanced error messages showing type provenance (declared vs inferred)
184
- - Legacy compatibility constants maintained for backward compatibility
185
-
186
- ### Examples Directory
187
-
188
- The `examples/` directory contains examples showing Kumi usage patterns:
189
- - `cascade_demonstration.rb` - Demonstrates cascade logic with UnsatDetector fixes (working)
190
- - `working_comprehensive_schema.rb` - Feature showcase (current best practices, working)
191
- - Mathematical predicate examples - Safe mutual recursion patterns using cascade mutual exclusion
192
- - `federal_tax_calculator_2024.rb` - Real-world tax calculation example (working)
193
- - `tax_2024.rb` - Tax example with explain functionality (working)
194
- - `wide_schema_compilation_and_evaluation_benchmark.rb` - Benchmark for wide schemas (compilation and evaluation)
195
- - `deep_schema_compilation_and_evaluation_benchmark.rb` - Performance benchmark for deep dependency chains (stack-safe evaluation)
196
- - `comprehensive_god_schema.rb` - Complex example (currently has UnsatDetector semantic errors)
197
-
198
- *Note: Some examples may use deprecated syntax and should be updated to use the new input block system.*
199
-
200
- ## Test Structure
201
-
202
- - `spec/kumi/` - Unit tests for core components
203
- - `spec/integration/` - Integration tests for full workflows
204
- - `spec/fixtures/` - Test fixtures and sample schemas
205
- - `spec/support/` - Test helpers (`ast_factory.rb`, `schema_generator.rb`)
206
126
 
207
127
  ## Files for Understanding
208
128
 
@@ -210,46 +130,8 @@ The `examples/` directory contains examples showing Kumi usage patterns:
210
130
  - `examples/*` Random examples of diverse contexts.
211
131
 
212
132
  ### Troubleshooting Schema Issues
213
- - **Parse Errors**: Check function syntax (avoid empty `fn()` calls)
214
- - **Module Not Found**: Check module structure and naming, see examples
215
- - **UnsatDetector Errors**: Review trait logic for contradictions, add debugs!
216
- - **Type Errors**: Check input block type declarations match usage, add debugs!
217
- - **Runtime Errors**: Use explain to trace computation dependencies, add debugs!
133
+ DEBUG, DEBUG. DEBUG LOGS!
218
134
 
219
- ## Input Block System Details
220
-
221
- ### Required Input Blocks
222
- - **All schemas must have an input block** -
223
- - Input blocks declare expected fields with optional type and domain constraints
224
- - **Empty input blocks are allowed** -`input {}` Even if not useful.
225
- - Fields are accessed via `input.field_name` or `input.field.nested_field.nested_nested_field` which
226
- works for referencing nested array input declarations.
227
-
228
- ### Type System Integration
229
- - **Declared Types**: Explicit type declarations in input blocks (e.g. `integer :field`, `string :name`, `any :field`)
230
- - **Inferred Types**: Types automatically inferred from expression analysis
231
- - **Type Checking**: Validates compatibility between declared and inferred types
232
- - **Enhanced Errors**: Error messages show type provenance (declared vs inferred)
233
- - **Helper Functions**: Use `array(:type)` and `hash(:key_type, :value_type)` for complex types
234
-
235
- ### Parser Components
236
- See `lib/kumi/ruby_parser/parser.rb`
237
-
238
- ### Domain Constraints
239
- - Can be declared: `integer :age, domain: 18..65`
240
- - Supports Range domains (`18..65`), Array domains (`%w[active inactive]`), and Proc domains for custom validation
241
- - Analyzer do some limited domain UNSAT detection, and its used to validated against input at Runtime
242
- ### Type Examples
243
- ```ruby
244
- input do
245
- string :name
246
- integer :age, domain: 18..65
247
- hash :metadata, key: { type: :string }, val: { type: :any }
248
-
249
- #generic type
250
- any :misc # this reduces Kumi's analyze/inference capabilities
251
- end
252
- ```
253
135
 
254
136
  ### Array Broadcasting System
255
137
 
@@ -262,6 +144,9 @@ input do
262
144
  float :price
263
145
  integer :quantity
264
146
  string :category
147
+ array :prices do
148
+ element :integer, :val
149
+ end
265
150
  end
266
151
  end
267
152
 
@@ -269,112 +154,3 @@ end
269
154
  value :subtotals, input.line_items.price * input.line_items.quantity
270
155
  trait :is_taxable, (input.line_items.category != "digital")
271
156
  ```
272
-
273
- **Aggregation Operations**: Functions consuming arrays are detected:
274
- ```ruby
275
- value :total_subtotal, fn(:sum, subtotals)
276
- value :avg_price, fn(:avg, input.line_items.price)
277
- value :max_quantity, fn(:max, input.line_items.quantity)
278
- ```
279
-
280
- **Implementation Components**:
281
- - **InputElementReference** AST nodes for nested field access paths
282
- - **BroadcastDetector** analyzer pass identifies vectorized vs scalar operations
283
- - **Compiler** generates appropriate map/reduce functions based on usage context
284
- - **Type Inference** infers types for array element operations
285
- - Supports arbitrary depth field access with nested arrays and hashes
286
-
287
- ### Trait Syntax Evolution
288
-
289
- **Current Syntax** (recommended):
290
- ```ruby
291
- trait :adult, (input.age >= 18)
292
- trait :qualified, (input.age >= 21) & (input.score > 80) & (input.verified == true)
293
- ```
294
-
295
- **Composite Trait Syntax** (NEW - bare identifier references):
296
- ```ruby
297
- # Base traits
298
- trait :adult, (input.age >= 18)
299
- trait :verified, (input.verified == true)
300
- trait :high_score, (input.score > 80)
301
-
302
- # Composite traits using bare identifier syntax
303
- trait :eligible, adult & verified & high_score
304
- trait :mixed, adult & (input.income > 50_000) & verified
305
-
306
- # Backward compatibility - both syntaxes work together
307
- trait :legacy_mix, adult & ref(:verified) & (input.score > 90)
308
- ```
309
-
310
- **Deprecated Syntax** (with warnings):
311
- ```ruby
312
- trait :adult, input.age, :>=, 18 # OLD - shows deprecation warning
313
- trait :qualified, input.age, :>=, 21, input.score # OLD - shows deprecation warning
314
- ```
315
-
316
- **Key Changes**:
317
- - **NEW**: Bare identifier syntax for direct trait reference: `adult` instead of `ref(:adult)`
318
- - New syntax uses parenthesized expressions: `trait :name, (expression)`
319
- - FieldRef nodes have operator methods that create CallExpression nodes
320
- - Logical AND chaining via `&` operator (Ruby limitation prevents `&&`)
321
- - Only AND operations supported to maintain constraint satisfaction system
322
- - **Backward Compatible**: Both `trait_name` and `ref(:trait_name)` work together
323
- - Old syntax maintained with deprecation warnings for backward compatibility
324
-
325
- ## Common Development Tasks
326
-
327
- ### Adding New Analyzer Passes
328
- 1. Create pass class inheriting from `PassBase` in `lib/kumi/analyzer/passes/`
329
- 2. Implement `run(errors)` method that calls `set_state(key, value)` to store results
330
- 3. Add pass to `PASSES` array in `lib/kumi/analyzer.rb` in correct order
331
- 4. Consider dependencies on other passes (e.g., TypeChecker needs TypeInferencer)
332
-
333
- ## Architecture Design Principles
334
-
335
- - **Multi-pass Analysis**: Each analysis pass has a single responsibility and builds on previous passes
336
- - **Immutable Syntax Tree**: AST nodes are immutable; analysis results stored separately in analyzer state
337
- - **Dependency-driven Evaluation**: All computation follows dependency graph for correct order
338
- - **Type Safety**: Optional type checking without breaking existing schemas
339
- - **Ruby Integration**: Leverages Ruby's metaprogramming with structured analysis
340
- - **Unified Error Reporting**: Consistent, localized error messages throughout the system with clear interface patterns
341
-
342
- ## Code Organization Patterns
343
-
344
- ### Testing Best Practices
345
- - **Spec Organization**: Tests organized by component with clear separation between unit and integration tests
346
- - **Error Variable Extraction**: RSpec patterns avoid multiline block chains by extracting error variables for assertion
347
-
348
- ## Development Guides and Standards
349
-
350
- ### Error Reporting Standards
351
- **For Parser Classes**:
352
- ```ruby
353
- class MyParser
354
- include ErrorReporting
355
-
356
- def parse_something
357
- # Error raising
358
- raise_syntax_error("Invalid syntax", location: current_location)
359
- end
360
- end
361
- ```
362
-
363
- **For Analyzer Passes**:
364
- ```ruby
365
- class MyAnalyzerPass < PassBase
366
- def run(errors)
367
- # Error accumulation with enhanced location
368
- report_error(errors, "semantic error", location: node.loc, type: :semantic)
369
-
370
- # Backward compatible method
371
- add_error(errors, node.loc, "legacy format error")
372
- end
373
- end
374
- ```
375
- ### Testing Error Scenarios
376
- - Use `spec/integration/dsl_breakage_spec.rb` patterns for error testing
377
- - Use `spec/integration/potential_breakage_spec.rb` for edge cases break
378
- - Use `spec/fixtures/location_tracking_test_schema.rb` fixture for testing different syntax error types
379
-
380
- #
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/amuta/kumi/workflows/CI/badge.svg)](https://github.com/amuta/kumi/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/kumi.svg)](https://badge.fury.io/rb/kumi)
5
5
 
6
- Kumi is a Declarative logic and rules engine framework with static analysis for Ruby.
6
+ **Kumi** is a declarative rules-and-calculation DSL for Ruby. It compiles business logic into a **typed, analyzable dependency graph** with **vector semantics** over nested data, performs **static checks** at definition time, **lowers to a compact IR**, and executes **deterministically**.
7
7
 
8
8
  It handles complex, interdependent calculations with validation and consistency checking.
9
9
 
@@ -66,7 +66,7 @@ Validation happens during schema definition.
66
66
  ## Installation
67
67
 
68
68
  ```bash
69
- # Requires Ruby 3.0+
69
+ # Requires Ruby 3.1+
70
70
  # No external dependencies
71
71
  gem install kumi
72
72
  ```
@@ -436,8 +436,8 @@ runner[:after_tax] # => 196,844.80 (cached)
436
436
  - Sequential procedural workflows
437
437
  - High-frequency processing
438
438
 
439
- ## JavaScript Transpiler
440
-
439
+ ## JavaScript Transpiler (V 0.0.10)
440
+ Note: On the current 0.0.11 this is disabled but will be back in later versions. reason: IR/Interpreter update.
441
441
  Transpiles compiled schemas to standalone JavaScript code. See [docs/features/javascript-transpiler.md](docs/features/javascript-transpiler.md) for details.
442
442
 
443
443
  ```ruby
@@ -465,7 +465,7 @@ See [docs/features/performance.md](docs/features/performance.md) for detailed be
465
465
 
466
466
  ## What Kumi does not guarantee
467
467
 
468
- Lambdas (e.g. -> inside the schema), external IO, floating-point vs bignum, JS transpiler edge cases, time-zone math differences, etc.
468
+ Lambdas (e.g. -> inside the schema), external IO, floating-point vs bignum, time-zone math differences, etc.
469
469
 
470
470
  ## Learn More
471
471
 
data/docs/SYNTAX.md CHANGED
@@ -214,12 +214,14 @@ Array broadcasting enables element-wise operations on array fields with automati
214
214
 
215
215
  ```ruby
216
216
  input do
217
+ # Structured array with defined fields
217
218
  array :line_items do
218
219
  float :price
219
220
  integer :quantity
220
221
  string :category
221
222
  end
222
223
 
224
+ # Nested arrays with hash objects
223
225
  array :orders do
224
226
  array :items do
225
227
  hash :product do
@@ -229,6 +231,15 @@ input do
229
231
  integer :quantity
230
232
  end
231
233
  end
234
+
235
+ # Dynamic arrays with flexible element types
236
+ array :api_responses do
237
+ element :any, :response_data # For dynamic/unknown hash structures
238
+ end
239
+
240
+ array :measurements do
241
+ element :float, :value # For simple scalar arrays
242
+ end
232
243
  end
233
244
  ```
234
245
 
@@ -290,6 +301,61 @@ value :avg_line_total, fn(:avg, line_totals)
290
301
  trait :has_expensive, fn(:any?, expensive_items)
291
302
  ```
292
303
 
304
+ ### Dynamic Hash Elements with `element :any`
305
+
306
+ For arrays containing hash data with unknown or flexible structure, use `element :any` instead of defining explicit hash objects:
307
+
308
+ ```ruby
309
+ input do
310
+ array :api_responses do
311
+ element :any, :response_data
312
+ end
313
+
314
+ array :user_profiles do
315
+ element :any, :profile_info
316
+ end
317
+ end
318
+
319
+ # Access hash data using fn(:fetch)
320
+ value :response_codes, fn(:fetch, input.api_responses.response_data, "status")
321
+ value :user_names, fn(:fetch, input.user_profiles.profile_info, "name")
322
+ value :user_ages, fn(:fetch, input.user_profiles.profile_info, "age")
323
+
324
+ # Mathematical operations on extracted values
325
+ value :avg_response_time, fn(:mean, fn(:fetch, input.api_responses.response_data, "response_time"))
326
+ value :total_users, fn(:size, input.user_profiles.profile_info)
327
+
328
+ # Traits using dynamic data
329
+ trait :success_responses, fn(:any?, fn(:fetch, input.api_responses.response_data, "status") == 200)
330
+ trait :adult_users, fn(:any?, fn(:fetch, input.user_profiles.profile_info, "age") >= 18)
331
+ ```
332
+
333
+ **Use Cases for `element :any`:**
334
+ - API responses with varying schemas
335
+ - Configuration data with flexible structure
336
+ - Dynamic hash structures (unknown keys at schema definition time)
337
+ - Legacy data where hash structure may vary
338
+ - When you need maximum flexibility without type constraints
339
+
340
+ **Comparison: `element :any` vs Hash Objects**
341
+
342
+ ```ruby
343
+ # element :any approach (flexible, dynamic)
344
+ array :users do
345
+ element :any, :data
346
+ end
347
+ value :names, fn(:fetch, input.users.data, "name")
348
+
349
+ # hash object approach (typed, structured)
350
+ array :users do
351
+ hash :data do
352
+ string :name
353
+ integer :age
354
+ end
355
+ end
356
+ value :names, input.users.data.name
357
+ ```
358
+
293
359
  ### Broadcasting Type Inference
294
360
 
295
361
  The type system automatically infers appropriate types: