Skip to content

feat: add GetDefaultManifold helper and protect manifold utilities - #54

Merged
lwJi merged 4 commits into
mainfrom
feature/add-GetDefaultManifold-helper
Jan 9, 2026
Merged

feat: add GetDefaultManifold helper and protect manifold utilities#54
lwJi merged 4 commits into
mainfrom
feature/add-GetDefaultManifold-helper

Conversation

@lwJi

@lwJi lwJi commented Jan 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add GetDefaultManifold[] function to centralize access to the first defined manifold
  • Refactor GetDefaultChart[] and GetDim[] to use the new helper for consistency
  • Add Protect calls to GetDefaultManifold, GetDefaultChart, and GetDim to prevent accidental redefinition

Test plan

  • Run wolframscript -script test/AllTests.wl to verify no regressions
  • Verify GetDefaultManifold[] returns the first manifold correctly
  • Verify GetDefaultChart[] and GetDim[] continue to work as expected

Introduce GetDefaultManifold[] function to centralize access to the first
defined manifold. Refactor GetDefaultChart and GetDim to use this helper
for consistency. Add Protect calls to prevent accidental redefinition.
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Code Review

Summary

This PR introduces a GetDefaultManifold[] helper function to centralize manifold access and adds Protect calls to prevent accidental redefinition of manifold utility functions. The refactoring improves code consistency and maintainability.

Strengths

  1. Good Refactoring: The new GetDefaultManifold[] function eliminates code duplication and provides a single source of truth for accessing the default manifold.

  2. Consistency: Refactoring GetDefaultChart[] and GetDim[] to use the new helper improves consistency across the codebase.

  3. Protection: Adding Protect calls to these utility functions is a good defensive programming practice that prevents accidental redefinition.

  4. Following Patterns: The implementation follows the established patterns in the codebase (similar to other getter functions starting at line 104).

Issues and Concerns

1. Missing Error Handling (High Priority)

The new GetDefaultManifold[] function at src/Basic.wl:210-211 directly accesses $Manifolds[[1]] without checking if the list is empty. If no manifolds have been defined, this will throw a runtime error: Part::partw: Part 1 of {} does not exist.

Impact: This affects all callers including GetDefaultChart[] (src/Basic.wl:216), GetDim[] (src/Basic.wl:221), and DefineTensor in src/Varlist.wl:213.

Recommendation: Add error checking to handle the empty manifolds case gracefully.

2. Missing Test Coverage (Medium Priority)

The PR description mentions verifying that GetDefaultManifold[] returns the first manifold correctly, but no tests are added for the new function.

Recommendation: Add a test to test/unit/BasicTests.wl to verify GetDefaultManifold[] returns the expected manifold.

3. Documentation Gap (Low Priority)

The usage string at src/Basic.wl:55 is minimal. Consider enhancing documentation to clarify behavior when no manifolds are defined.

Code Quality Observations

  1. Style Consistency: The code follows the existing style conventions (Module usage, Return statements, Protect calls).

  2. No Performance Impact: The refactoring does not introduce performance concerns.

  3. No Security Issues: No security concerns identified.

Recommendations

Before merging:

  1. Critical: Add error handling for empty $Manifolds list
  2. Important: Add unit tests for GetDefaultManifold[]
  3. Nice-to-have: Enhance documentation

Overall Assessment

This is a solid refactoring PR that improves code organization. The main concern is the lack of error handling, which could cause runtime failures in edge cases. Once error handling and tests are added, this will be ready to merge.

Recommended action: Request changes to add error handling and tests before merging.

@lwJi

lwJi commented Jan 9, 2026

Copy link
Copy Markdown
Owner Author

@claude address the 3 concerns

@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Claude finished @lwJi's task in 1m 53s —— View job


All Code Review Concerns Addressed ✓

Successfully addressed all 3 concerns from the code review:

  • Add error handling for empty $Manifolds list in GetDefaultManifold[]
  • Add unit tests for GetDefaultManifold[]
  • Enhance documentation in usage string
  • Commit and push changes

Changes Made

1. Error Handling (High Priority) - src/Basic.wl:210-220

Added proper error handling for the empty manifolds case:

  • Checks if $Manifolds is empty before accessing the first element
  • Returns $Failed when no manifolds are defined
  • Displays helpful error message: "No manifolds have been defined. Use DefManifold to define a manifold."

2. Test Coverage (Medium Priority) - test/unit/BasicTests.wl:178-214

Added 3 comprehensive unit tests:

  • GetDefaultManifold-ReturnsFirstManifold: Verifies it returns a valid manifold symbol
  • GetDefaultManifold-ReturnsFirstInList: Verifies it returns specifically the first manifold
  • GetDefaultManifold-EmptyManifolds-ReturnsFailed: Verifies error handling when no manifolds exist

3. Documentation (Low Priority) - src/Basic.wl:55

Enhanced the usage string to clarify behavior:

  • Updated from: "GetDefaultManifold[] returns the first defined manifold."
  • Updated to: "GetDefaultManifold[] returns the first defined manifold. Returns $Failed if no manifolds have been defined."

Testing Note

The wolframscript test runner is not available in this CI environment, but the tests have been added following the existing test patterns in BasicTests.wl. You can run them locally with:

wolframscript -script test/AllTests.wl

Commit

Pushed to feature/add-GetDefaultManifold-helper as commit a6f4802.


|

- Add error handling for empty $Manifolds list (returns $Failed with message)
- Add 3 unit tests for GetDefaultManifold[] covering normal and edge cases
- Enhance usage string to document behavior when no manifolds are defined

Co-authored-by: Liwei Ji <lwJi@users.noreply.github.com>
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Code Review

Summary

This PR introduces a good refactoring that centralizes manifold access through a new GetDefaultManifold[] helper function. The changes improve code maintainability and add proper protection against accidental redefinition.

Positive Aspects ✓

  1. Good Abstraction: The new GetDefaultManifold[] function follows DRY principle and centralizes the $Manifolds[[1]] access pattern
  2. Error Handling: Proper error handling with a descriptive message when no manifolds are defined
  3. Comprehensive Tests: Three well-designed unit tests covering normal operation, verification of first element return, and edge case handling
  4. Consistent Style: Follows existing code patterns in Basic.wl (Module usage, Return statements, Protect calls)
  5. Good Documentation: Usage string clearly documents the return behavior including the $Failed case

Issues & Recommendations

1. Cascading Failure Not Handled (Medium Priority)

When GetDefaultManifold[] returns $Failed, the calling functions GetDefaultChart[] and GetDim[] will fail with cryptic xAct errors:

GetDefaultChart[] :=
  Return[ChartsOfManifold[GetDefaultManifold[]][[1]]];

If GetDefaultManifold[] returns $Failed, then ChartsOfManifold[$Failed] will likely produce an error.

Recommendation: Add error checking in the callers:

GetDefaultChart[] :=
  Module[{manifold = GetDefaultManifold[]},
    If[manifold === $Failed,
      Return[$Failed],
      Return[ChartsOfManifold[manifold][[1]]]
    ]
  ];

2. Missed Refactoring Opportunity (Low Priority)

The file src/Varlist.wl:213 still uses $Manifolds[[1]] directly:

Module[{manifold = $Manifolds[[1]]},

Recommendation: Consider updating this to use GetDefaultManifold[] for consistency, though it may require additional error handling in that context.

3. Unnecessary Module Wrapper (Code Style - Low Priority)

The GetDefaultManifold[] function uses Module[{}, ...] with no local variables:

GetDefaultManifold[] :=
  Module[{},
    If[Length[$Manifolds] === 0,
      ...
    ]
  ];

Recommendation: The Module wrapper is unnecessary here. Simpler:

GetDefaultManifold[] :=
  If[Length[$Manifolds] === 0,
    Message[GetDefaultManifold::NoManifolds];
    $Failed,
    $Manifolds[[1]]
  ];

Note: Also can simplify by using $Failed without Return[] in the If statement.

4. Test Coverage Gap (Low Priority)

The test suite doesn't verify the protected status of the functions. Consider adding:

VerificationTest[
  (* Attempt to redefine should fail *)
  Check[
    GetDefaultManifold[] := "redefined";
    False,
    True,
    {Set::wrsym, SetDelayed::wrsym}
  ],
  True,
  TestID -> "GetDefaultManifold-Protected"
]

Performance & Security

  • Performance: No concerns. The changes are lightweight accessors.
  • Security: No concerns. Appropriate use of Protect prevents accidental modification.

Overall Assessment

This is a solid refactoring that improves code quality. The main concern is error propagation in GetDefaultChart[] and GetDim[], which should be addressed to prevent confusing error messages when no manifolds are defined.

Recommendation: Approve after addressing issue #1 (cascading failures), or add TODO comments acknowledging the limitation.

@lwJi

lwJi commented Jan 9, 2026

Copy link
Copy Markdown
Owner Author

@claude address issue 1

@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Claude finished @lwJi's task in 1m 52s —— View job


Issue #1 Resolved: Cascading Failure Handling ✓

Successfully added error handling to prevent cascading failures when GetDefaultManifold[] returns $Failed.

Tasks:

  • Read current implementation in src/Basic.wl
  • Add error handling to GetDefaultChart[]
  • Add error handling to GetDim[]
  • Add tests for error cases
  • Commit and push changes

Changes Made

1. Error Handling in GetDefaultChart[] - src/Basic.wl:224-230

GetDefaultChart[] :=
  Module[{manifold = GetDefaultManifold[]},
    If[manifold === $Failed,
      Return[$Failed],
      Return[ChartsOfManifold[manifold][[1]]]
    ]
  ];

Now returns $Failed gracefully instead of causing cryptic xAct errors when no manifolds exist.

2. Error Handling in GetDim[] - src/Basic.wl:234-240

GetDim[] :=
  Module[{manifold = GetDefaultManifold[]},
    If[manifold === $Failed,
      Return[$Failed],
      Return[DimOfManifold[manifold]]
    ]
  ];

Now returns $Failed gracefully instead of causing cryptic xAct errors when no manifolds exist.

3. Test Coverage - test/unit/BasicTests.wl

Added 2 new tests to verify error handling:

  • GetDefaultChart-EmptyManifolds-ReturnsFailed: Verifies GetDefaultChart[] returns $Failed when no manifolds exist
  • GetDim-EmptyManifolds-ReturnsFailed: Verifies GetDim[] returns $Failed when no manifolds exist

Both tests use Block[{$Manifolds = {}}, ...] to simulate the empty manifolds case and Quiet[] to suppress expected error messages.

Summary

All three functions (GetDefaultManifold, GetDefaultChart, GetDim) now handle the case where no manifolds are defined consistently:

  1. They check for the empty manifolds case
  2. They return $Failed with a clear error message
  3. They don't cause cascading failures with cryptic xAct errors

Testing Note

The tests follow the existing pattern in BasicTests.wl and can be run locally with:

wolframscript -script test/AllTests.wl

--- | Latest commit

…ading failures

- Add error checks in GetDefaultChart[] to return $Failed when GetDefaultManifold[] fails
- Add error checks in GetDim[] to return $Failed when GetDefaultManifold[] fails
- Add tests for GetDefaultChart-EmptyManifolds-ReturnsFailed
- Add tests for GetDim-EmptyManifolds-ReturnsFailed

This prevents cryptic xAct errors when no manifolds are defined.

Co-authored-by: Liwei Ji <lwJi@users.noreply.github.com>
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Pull Request Review

Summary

This PR introduces a GetDefaultManifold[] helper function to centralize manifold access, refactors existing functions to use it, adds error handling for edge cases, and protects these functions from accidental redefinition. Overall, this is a well-structured improvement that enhances code quality and robustness.


Strengths

1. Excellent Code Refactoring

  • Introduces proper DRY principle by extracting $Manifolds[[1]] into a single function
  • Makes the codebase more maintainable - future changes to manifold access logic only need to happen in one place
  • Consistent error handling pattern across all three functions

2. Robust Error Handling

  • Proper edge case handling when $Manifolds is empty
  • Clear error messages that guide users to the solution
  • Prevents cryptic xAct errors by catching issues early with $Failed returns
  • Error propagation in GetDefaultChart[] and GetDim[] is well-designed

3. Comprehensive Test Coverage

  • 5 new unit tests covering normal and edge cases
  • Tests verify both success paths and error conditions
  • Proper use of Quiet[] to suppress expected error messages in tests
  • Tests use Block with $Manifolds to safely test edge cases without affecting test state

4. Good Coding Practices

  • Protect[] calls prevent accidental redefinition - important for library code
  • Usage documentation strings are clear and complete
  • Consistent code style matching the existing codebase

Minor Issues and Suggestions

1. Redundant Return Statements (Style Issue)

In Wolfram Language, the last expression in a Module is automatically returned. The explicit Return[] calls are unnecessary at src/Basic.wl:210-218, 224-232, 234-242.

However, I notice the existing codebase uses explicit Return[] throughout (e.g., lines 105, 117, 127, 139, etc.), so this is consistent with the project style. This is perfectly acceptable - just noting it as a style choice.

2. Empty Module Variable List

Module[{}, with an empty variable list can be simplified. However, this pattern is used consistently throughout the codebase, so this matches project conventions.

3. Potential Index Out of Bounds in GetDefaultChart

At src/Basic.wl:228:
Return[ChartsOfManifold[manifold][[1]]]

If a manifold has been defined but has no charts, this will fail with an index error. Consider adding a check for empty charts list. Though in practice, this may never happen if DefManifold always creates charts. Worth considering if this is a realistic edge case.


Performance Considerations

No concerns. The changes are simple lookups and conditional checks with negligible performance impact.


Security Considerations

No concerns. This is a utility library for mathematical code generation with no security implications. The Protect[] calls are actually a security feature preventing accidental modification.


Code Quality Assessment

Correctness: 5/5 - Logic is sound, error handling is proper
Maintainability: 5/5 - Excellent refactoring, DRY principle applied
Test Coverage: 5/5 - Comprehensive tests for all code paths
Documentation: 5/5 - Clear usage strings and error messages
Code Style: 5/5 - Consistent with existing codebase


Recommendation

APPROVE - This is a high-quality PR that improves code maintainability, adds important error handling, and includes thorough test coverage. The minor style suggestions are just that - suggestions - and the code is perfectly acceptable as-is.

The only actionable item to consider is the potential edge case in GetDefaultChart[] if a manifold exists without charts, but this may not be a realistic scenario in your workflow.


Suggested Checklist Before Merge:

  • Run full test suite
  • Consider the GetDefaultChart[] edge case mentioned above (or document why it is not needed)
  • Verify no other code directly accesses $Manifolds[[1]] that should use the new helper

Great work on this refactoring!

@lwJi
lwJi merged commit 0b68a01 into main Jan 9, 2026
1 check passed
@lwJi
lwJi deleted the feature/add-GetDefaultManifold-helper branch January 9, 2026 17:45
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