# Requirements and Implementation Guidance for Baba Yaga C Implementation ## Response to C Implementation Team Questions ### Scope Chain Semantics **Q: When evaluating a sequence of statements, are all variable declarations and lookups expected to occur in the same (global) scope?** **A:** **CORRECTION**: The JavaScript implementation uses a **hybrid scope model** with both global and local scopes. **Key Points:** - **Global Scope**: All top-level variable declarations and function definitions are stored in a single global environment object - **Local Scopes**: Function calls create new local scopes using prototypal inheritance (`Object.create(globalScope)`) - **Variable Lookup**: Local scopes inherit from global scope, allowing access to global variables - **Function Parameters**: Create local variables in the function's scope **Q: Are there any cases where a new scope is created implicitly?** **A:** **CORRECTION**: Yes, the JavaScript implementation creates local scopes for function calls. **Scope Creation:** - **Function Calls**: Create new local scopes using `Object.create(globalScope)` - **Function Parameters**: Become local variables in the function scope - **`when` expressions**: No new scope created - **Table literals**: No new scope created - **Other constructs**: No new scope created ### Variable Lookup and Shadowing **Q: If a variable is declared in a sequence, is it immediately available for lookup in subsequent statements?** **A:** **CORRECTION**: Yes, for global variables. However, local variables in function scopes are only available within that function. **Global Scope Behavior:** ``` x : 5; y : 3; sum : x + y; // x and y are immediately available in global scope ``` **Local Scope Behavior:** ``` func : (param) -> { local : param + 1; // local is only available within this function return local; }; // local is NOT available here in global scope ``` **Q: How does the JS implementation handle variable shadowing or redeclaration?** **A:** **CORRECTION**: The JavaScript implementation uses **prototypal inheritance shadowing** for local scopes and **overwrites** for global redeclaration. **Behavior:** - **Global Scope**: Variable redeclaration overwrites the previous value (no error) - **Local Scopes**: Function parameters and local variables shadow global variables - **Lookup Order**: Local scope first, then global scope (prototypal inheritance) - **No Block Scoping**: No nested block-level scopes exist **Global Redeclaration Example:** ``` x : 5; x : 10; // x is now 10, previous value 5 is lost result : x; // result = 10 ``` **IMPORTANT CORRECTION**: The above redeclaration behavior appears to be incorrect based on functional programming principles and test evidence. See the "Variable Redeclaration" section below for the corrected implementation. **Local Shadowing Example:** ``` global_var : 5; func : (global_var) -> { // global_var parameter shadows the global variable return global_var + 1; // uses parameter, not global }; result : func(10); // result = 11, global_var still = 5 ``` ### Table Pattern Matching **Q: When matching a table pattern in a when expression, is the pattern table compared by key and value only?** **A:** Yes, table pattern matching is a **simple key-value comparison**. The JavaScript implementation performs a shallow comparison of table properties. **Matching Rules:** - Keys must match exactly (string comparison) - Values must be equal (using `===` semantics) - No prototype chain traversal - No hidden property checking - No deep object comparison **Example:** ``` table : {a: 1, b: 2}; result : when table {a: 1, b: 2} -> "exact match" {a: 1} -> "partial match" _ -> "no match" ``` **Q: Are there edge cases in table pattern matching?** **A:** The JavaScript implementation treats table patterns as simple object comparisons. No special edge cases beyond standard JavaScript object equality semantics. ### Function Call Semantics **Q: What are the exact rules for when an identifier is treated as a function vs. a value?** **A:** The JavaScript implementation uses **parse-time function detection** based on syntax, not runtime type checking. **Function Call Rules:** 1. **Parse-time detection**: If an identifier is followed by parentheses `()` or expressions that could be arguments, it's treated as a function call 2. **Scope creation**: Function calls create new local scopes using prototypal inheritance 3. **No runtime type checking**: The system doesn't verify if the identifier actually contains a function 4. **Runtime errors**: If you call a non-function value, it will attempt to execute it as a function (causes runtime error) **Examples:** ``` x : 5; func : (a, b) -> a + b; result1 : func(1, 2); // Function call - works result2 : x(1, 2); // Non-function call - runtime error ``` **Important:** The distinction is made at parse time based on syntax, not at runtime based on the actual value type. ### Test 05 IO Operations **Q: Are there any known quirks regarding order of evaluation or scope for IO operations?** **A:** IO operations follow the same global scope rules as all other operations. **IO Behavior:** - IO operations use the current scope (global or local) - No special scoping for IO functions - Order of evaluation follows normal left-to-right sequence evaluation - IO operations can reference any variables in the current scope **Example:** ``` x : 5; print(x); // Prints 5 y : 10; print(y); // Prints 10 print(x + y); // Prints 15 ``` ### Implementation Recommendations **For C Implementation:** 1. **Hybrid Scope Model**: Implement both global scope and local function scopes 2. **Prototypal Inheritance**: Local scopes should inherit from global scope 3. **Variable Lookup Order**: Local scope first, then global scope 4. **Function Parameter Scoping**: Function parameters create local variables 5. **Simple Table Comparison**: Use shallow key-value comparison for table pattern matching 6. **Parse-time Function Detection**: Determine function calls at parse time, not runtime 7. **Allow Global Redeclaration**: Permit variable redeclaration in global scope without errors **Key Implementation Pattern:** ```c // Global environment typedef struct { char* name; Value value; } Variable; Variable* global_env[MAX_VARS]; int global_env_size = 0; // Local scope (for function calls) typedef struct { Variable* local_vars[MAX_VARS]; int local_size; Variable** parent_scope; // Reference to global scope } LocalScope; // Variable lookup: check local scope first, then global scope ``` ## Variable Redeclaration **Q: Is variable redeclaration allowed?** **A:** **NO** - Variable redeclaration is NOT allowed in Baba Yaga. This is a functional programming language where all values are immutable once declared. **Evidence:** - None of the test files contain variable redeclarations - Functional programming principles require immutability - Current C implementation correctly prevents redeclaration (returns false if variable exists) **Implementation:** When defining a variable, if it already exists in the current scope, return an error rather than overwriting the value. **Note:** The JS team's previous response about allowing redeclaration appears to be incorrect or outdated. The language design clearly favors functional programming principles. ### Testing Strategy **Focus Areas for C Implementation:** 1. Verify hybrid scope model (global + local function scopes) 2. Test variable shadowing in function parameters 3. Confirm table pattern matching uses simple key-value comparison 4. Validate parse-time function call detection 5. Ensure IO operations use current scope (global or local) **Critical Test Cases:** - Variable redeclaration in global scope (should overwrite, not error) - Function parameter shadowing of global variables - Cross-statement variable access in global scope - Local variable isolation within functions - Table pattern matching with exact and partial matches - Function calls vs. value references - IO operations with variables from current scope This should resolve the scope-related test failures and ensure the C implementation matches the JavaScript reference semantics exactly.