Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow structural recursion in type aliases #1207

Merged
merged 26 commits into from
Dec 18, 2024

Conversation

antoniosarosi
Copy link
Contributor

@antoniosarosi antoniosarosi commented Dec 2, 2024

Allow structural recursion (like TS):

type RecursiveMap = map<string, RecursiveMap>

type A = A[]

Follow up on #1163


Important

Enable structural recursion in type aliases by updating cycle validation logic, adding tests, and supporting recursive type aliases in Python, Ruby, and TypeScript clients.

  • Behavior:
    • Allow structural recursion for type alias cycles involving maps and lists in cycle.rs.
    • Update validate() in cycle.rs to handle structural recursion and report cycles.
    • Modify ParserDatabase::finalize_dependencies() in lib.rs to resolve type aliases and handle cycles.
  • Functions:
    • Add insert_required_alias_deps() in cycle.rs to handle alias dependencies.
    • Rename insert_required_deps() to insert_required_class_deps() in cycle.rs.
  • Models:
    • Add structural_recursive_alias_cycles to Types in mod.rs.
  • Tests:
    • Update recursive_type_aliases.baml to reflect new cycle validation behavior.
    • Add tests in lib.rs to verify structural recursion handling.
  • Language Support:
    • Update Python, Ruby, and TypeScript clients to handle recursive type aliases.
  • Misc:
    • Add is_subtype() to IRHelper in mod.rs to support subtyping checks.
    • Add coerce_alias() in coerce_alias.rs to handle alias coercion.
    • Add integration tests for recursive alias cycles in integ-tests/typescript/tests/integ-tests.test.ts.

This description was created by Ellipsis for 8ff0397. It will automatically update as commits are pushed.

Copy link

vercel bot commented Dec 2, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
baml ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 18, 2024 7:28pm

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Reviewed everything up to e38e5e7 in 53 seconds

More details
  • Looked at 286 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 6 drafted comments based on config settings.
1. engine/baml-lib/baml-core/src/validate/validation_pipeline/validations/cycle.rs:20
  • Draft comment:
    Consider using collect instead of HashMap::from_iter for better readability and idiomatic Rust.
let structural_type_aliases: HashMap<_, _> = ctx.db.walk_type_aliases().map(|alias| {
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The comment is about the use of HashMap::from_iter which can be replaced with collect for better readability and idiomatic Rust.
2. engine/baml-lib/baml-core/src/validate/validation_pipeline/validations/cycle.rs:50
  • Draft comment:
    Consider using collect instead of HashMap::from_iter for better readability and idiomatic Rust.
let class_dependency_graph: HashMap<_, _> = ctx.db.walk_classes().map(|class| {
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The comment is about the use of HashMap::from_iter which can be replaced with collect for better readability and idiomatic Rust.
3. engine/baml-lib/baml-core/src/validate/validation_pipeline/validations/cycle.rs:128
  • Draft comment:
    Consider refactoring this function to use a struct for managing state, as there are too many parameters being passed. This will improve code readability and maintainability.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The function insert_required_class_deps has a TODO comment about using a struct to manage state due to too many parameters. This is a valid concern and should be addressed to improve code maintainability.
4. engine/baml-lib/baml-core/src/validate/validation_pipeline/validations/cycle.rs:213
  • Draft comment:
    Consider refactoring this function to use a struct for managing state, similar to the suggestion for insert_required_class_deps. This will improve code readability and maintainability.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The function insert_required_alias_deps is similar to insert_required_class_deps and could also benefit from using a struct to manage state.
5. engine/baml-lib/parser-database/src/lib.rs:184
  • Draft comment:
    Consider including the actual dep value in the panic message for better debugging information.
panic!("Unknown class `{}`", dep)
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The panic messages in finalize_dependencies could be more informative by including the actual dep value that caused the panic.
6. engine/baml-lib/parser-database/src/lib.rs:188
  • Draft comment:
    Consider including the actual dep value in the panic message for better debugging information.
panic!("Unknown class `{}`", dep)
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The panic messages in finalize_dependencies could be more informative by including the actual dep value that caused the panic.

Workflow ID: wflow_P4qjyYzxcUhJMV6L


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Changes requested. Incremental review on 794b3f4 in 40 seconds

More details
  • Looked at 100 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/baml-lib/parser-database/src/types/mod.rs:284
  • Draft comment:
    Ensure that all references to structural_recursive_type_aliases are updated to structural_recursive_alias_cycles for consistency.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The renaming of structural_recursive_type_aliases to structural_recursive_alias_cycles in types/mod.rs should be consistent across the codebase. Ensure that all references are updated accordingly.

Workflow ID: wflow_2YiAGGktzCIRmBOI


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@@ -138,6 +138,11 @@ impl ParserDatabase {
self.types.resolved_type_aliases.insert(*alias_id, resolved);
}

// Cycles left here after cycle validation are allowed. Basically lists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here is misleading. It states that cycles left after validation are allowed, but the code actually rebuilds the cycles for rendering purposes. Consider updating the comment to reflect the actual behavior.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Changes requested. Incremental review on 9869707 in 31 seconds

More details
  • Looked at 102 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 drafted comments based on config settings.

Workflow ID: wflow_k6DHP92C4hBCSdkt


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

// TODO: @antoniosarosi: HashSet is random, won't always iterate in the
// same order. Fix this with IndexSet or something, we really don't want
// to sort this every single time.
let mut successors = Vec::from_iter(&self.graph[&node_id]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using IndexSet instead of HashSet for successors to maintain a consistent iteration order without needing to sort repeatedly.

@antoniosarosi antoniosarosi changed the title Allow structural recursion Allow structural recursion in type aliases Dec 5, 2024
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on fab92f5 in 37 seconds

More details
  • Looked at 1195 lines of code in 24 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. integ-tests/typescript/tests/integ-tests.test.ts:171
  • Draft comment:
    The test case 'single optional string' is missing an assertion. Consider adding an assertion to verify the expected behavior.
  • Reason this comment was not posted:
    Comment was not on a valid diff hunk.

Workflow ID: wflow_idjBdrhuZjILUbPJ


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on 18c1bde in 18 seconds

More details
  • Looked at 13 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/baml-lib/parser-database/src/lib.rs:329
  • Draft comment:
    The change from let mut db to let db is appropriate here since db is not modified after initialization. This aligns with Rust's best practices for immutability.
  • Reason this comment was not posted:
    Confidence changes required: 0%
    The change from let mut db to let db in the assert_finite_cycles function is unnecessary since db is not modified after its initialization. This change is correct and aligns with Rust's best practices for immutability.

Workflow ID: wflow_Xqma6UVtkZq3GKJT


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on c09997a in 1 minute and 17 seconds

More details
  • Looked at 3554 lines of code in 81 files
  • Skipped 4 files when reviewing.
  • Skipped posting 2 drafted comments based on config settings.
1. integ-tests/typescript/test-report.html:263
  • Draft comment:
    The test failure here is due to a missing service account file, which is likely an issue with the test environment setup rather than the code changes in this PR.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The test report indicates two failed tests. One is due to a missing service account file, and the other is due to a connection refused error. These issues are likely related to the test environment setup rather than the code changes in the PR.
2. integ-tests/typescript/test-report.html:265
  • Draft comment:
    The test failure here is due to a connection refused error, which is likely an issue with the test environment setup rather than the code changes in this PR.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The test report indicates two failed tests. One is due to a missing service account file, and the other is due to a connection refused error. These issues are likely related to the test environment setup rather than the code changes in the PR.

Workflow ID: wflow_nK4laF4giOXp81U3


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on 72ea8cb in 31 seconds

More details
  • Looked at 1290 lines of code in 29 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. integ-tests/typescript/baml_client/sync_client.ts:2146
  • Draft comment:
    Ensure that the SimpleRecursiveMapAlias function is correctly implemented and follows the pattern used in other similar functions. Verify that the input and output types are correctly defined and that the function handles errors appropriately.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The function SimpleRecursiveMapAlias is newly added in this PR. It is important to ensure that the function is correctly implemented and follows the pattern used in other similar functions.

Workflow ID: wflow_O04zlPHOFObJRnMX


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on abb7430 in 38 seconds

More details
  • Looked at 799 lines of code in 17 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. integ-tests/typescript/baml_client/sync_client.ts:1571
  • Draft comment:
    Ensure that the JsonTypeAliasCycle function correctly handles the JsonValue type for both input and output. The error handling logic should be consistent with other functions in this file.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The function JsonTypeAliasCycle is newly added in this PR. It is important to ensure that the function signature and implementation are correct. The function should handle the input and output types correctly, and the error handling should be consistent with other functions in the file.

Workflow ID: wflow_YDjIdt8Nxh8pEZv4


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on c4e8b85 in 32 seconds

More details
  • Looked at 608 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 drafted comments based on config settings.
1. engine/baml-lib/baml-core/src/ir/ir_helpers/mod.rs:227
  • Draft comment:
    The is_subtype function has a potential performance issue due to its O(n) complexity when handling recursive type aliases. Consider optimizing this to improve performance.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The is_subtype function has a potential performance issue due to its O(n) complexity when handling recursive type aliases. This could be optimized to improve performance.
2. engine/baml-lib/baml-core/src/ir/ir_helpers/to_baml_arg.rs:43
  • Draft comment:
    The coerce_arg function has a potential performance issue due to its O(n) complexity when handling recursive type aliases. Consider optimizing this to improve performance.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The is_subtype function in mod.rs and the coerce_arg function in to_baml_arg.rs both have a TODO comment about O(n) complexity. This indicates a potential performance issue that should be addressed.

Workflow ID: wflow_3r3kmKJKK0vcdLB4


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Changes requested. Incremental review on d6b1e9e in 43 seconds

More details
  • Looked at 63 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 drafted comments based on config settings.

Workflow ID: wflow_IozJLzp3syXuO4Rk


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

expect(res).toEqual({ one: { two: { three: {} } } })
})

it('simple recursive map alias', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate test case name 'simple recursive map alias'. Consider renaming for clarity.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on c5267b5 in 3 minutes and 7 seconds

More details
  • Looked at 42 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. integ-tests/typescript/test-report.html:263
  • Draft comment:
    The test 'json type alias cycle' failed, indicating a potential issue with the handling of recursive type aliases. Please investigate the cause of the discrepancy between the expected and received values.
  • Reason this comment was not posted:
    Comment was on unchanged code.

Workflow ID: wflow_XEyOmGGQRgg5zVq1


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on cac1a16 in 2 minutes and 23 seconds

More details
  • Looked at 77 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/baml-lib/jsonish/src/tests/test_aliases.rs:41
  • Draft comment:
    The test name test_json_without_nested_objects should be more descriptive, e.g., test_recursive_alias_without_nested_objects. This applies to other test names as well, such as test_json_with_nested_list and test_json_with_nested_object.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The test names should be descriptive and consistent with the test content.

Workflow ID: wflow_ZzoTCo5pmi0oumGr


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Changes requested. Incremental review on 39141cb in 1 minute and 7 seconds

More details
  • Looked at 149 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 drafted comments based on config settings.

Workflow ID: wflow_I35CvUUMutg0SHfC


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.


type RecAliasThree = RecAliasOne[]

type JsonValue = number | string | boolean | number | JsonObject | JsonArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type alias JsonValue includes number twice, which is redundant. Consider removing the duplicate number.

Suggested change
type JsonValue = number | string | boolean | number | JsonObject | JsonArray
type JsonValue = number | string | boolean | JsonObject | JsonArray

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on 401a97d in 48 seconds

More details
  • Looked at 14 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/language_client_codegen/src/ruby/field_type.rs:14
  • Draft comment:
    Consider documenting the limitation of using T.anything for RecursiveTypeAlias due to Sorbet's lack of support for recursive type aliases. This will help future developers understand the reasoning behind this choice.
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The implementation for FieldType::RecursiveTypeAlias returns T.anything, which is a placeholder and may not be the best representation for recursive type aliases in Ruby. However, given the comment that Sorbet does not support recursive type aliases, this might be the best workaround for now. It's important to note this limitation in the documentation or comments for future reference.

Workflow ID: wflow_fO5cZFTz09QoWC9h


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good to me! Incremental review on fc25050 in 53 seconds

More details
  • Looked at 21 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/language_client_codegen/src/openapi.rs:583
  • Draft comment:
    The error message could be more specific by including the unsupported key type:
anyhow::bail!(format!("BAML<->OpenAPI only supports strings, enums, and literal strings as map keys but got an unsupported key type: {key:?}"))
  • Reason this comment was not posted:
    Confidence changes required: 50%
    The error message should be more specific about the unsupported key type.

Workflow ID: wflow_z3xBtF5zYnqDlksr


You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@antoniosarosi antoniosarosi merged commit 4eb543a into antonio/type-aliases Dec 18, 2024
2 of 3 checks passed
@antoniosarosi antoniosarosi deleted the antonio/type-aliases-with-cycles branch December 18, 2024 19:23
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Changes requested. Incremental review on 8ff0397 in 3 minutes and 57 seconds

More details
  • Looked at 285 lines of code in 7 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 drafted comments based on config settings.
1. engine/baml-lib/jsonish/src/deserializer/coercer/field_type.rs:32
  • Draft comment:
    Remove the eprintln! macro as it is used for debugging purposes and should not be present in production code.
  • Reason this comment was not posted:
    Marked as duplicate.

Workflow ID: wflow_wKc9g7q5tmVnjuXf


Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

@@ -166,6 +166,7 @@ fn test_union_of_map_and_class() {
assert!(result.is_ok(), "Failed to parse: {:?}", result);

let value = result.unwrap();
dbg!(&value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the dbg! macro as it is meant for debugging and should not be present in production code.

}

eprintln!("ret_v: {:?}", ret_v);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the eprintln! macro as it is used for debugging purposes and should not be present in production code.

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