-
Notifications
You must be signed in to change notification settings - Fork 11
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
basic stack traces #261
base: main
Are you sure you want to change the base?
basic stack traces #261
Conversation
Warning Rate limit exceeded@doyougnu has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 31 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (32)
WalkthroughThis pull request introduces a comprehensive set of changes across multiple files in the Klister programming language project, focusing on error handling, debugging capabilities, and code formatting. The primary modifications include the introduction of a new Changes
Suggested labels
Suggested reviewers
Poem
Possibly related PRs
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (57)
examples/non-examples/error.golden (1)
1-5
: Great improvement in formatting the error messageThe transition to a multi-line format is much clearer and easier to read. As a further enhancement, consider adding more detail to the stack trace—such as which function or binding triggered the error—to give users deeper insight into the error’s origin.
examples/tiny-types.golden (2)
3-4
: Consistent indentation recommended
The formatting change increases clarity by separating the annotation and syntax symbol onto separate lines. However, consider using consistent indentation (e.g., 2 or 4 spaces) rather than a single leading space for<foo>
to improve readability across the file.
5-6
: Maintain uniform spacing for annotations and syntax symbols
Similar to lines 3-4, this change clarifies the code’s meaning, but line 6 uses additional leading spaces (six spaces) compared with other lines. Adopting a standard indentation convention will help maintain an overall uniform look.examples/primitives-documentation.golden (2)
31-33
: Consider aligning or grouping the type variables consistently.
Currently,∀(α : *)
is on a separate line from(β : *)
, which may be inconsistent with the style used elsewhere. Consolidate them if you prefer a uniform approach.
53-55
: Maintain consistent line breaks for type variables.
Like forbind-IO
, grouping both(α : *)
and(β : *)
on a single line might keep it uniform with other similar signatures.examples/non-examples/stack-traces/error-in-cons-head.golden (1)
1-2
: Consider adding a more descriptive message for clarity.
The current error message shows "Unknown" but doesn't specify what went wrong or how to fix it. Including further context (e.g., the type of error, expected vs. actual) can help users quickly diagnose the issue.examples/non-examples/stack-traces/error-in-bind-head.kl (1)
1-3
: Confirm the intended error-handling behavior in monadic context.
This example returns the result of(pure x)
after an error occurs. Clarify if this demonstration accurately reflects how>>=
should propagate errors or if additional handling is required.examples/non-examples/stack-traces/.#error-in-cons-head.golden (1)
1-1
: Potentially sensitive file path.
Revealing an absolute path in error messages can expose user-specific environment details. Consider redacting or abstracting these paths if they are not vital to debugging.examples/non-examples/stack-traces/error-in-cons-head.kl (1)
1-10
: Consider utilizing the function argument and addressing the TODO.Here,
(define fail (lambda (thing) (car '(1 2 'something-else))))
never uses thething
parameter, which may be confusing. If it’s intentional, consider documenting why. Also, the file has a TODO about testing pairs—ensure these tests are added for thorough coverage.Would you like me to draft a minimal test for pair scenarios?
examples/non-examples/stack-traces/error-in-case-constructor.kl (2)
5-7
: Consider clarifying the purpose of this large Alphabet type.
This type enumerates a range of letters, which may be overkill unless you're testing or demonstrating patterns. If this is purely for illustrative error handling, clarify or reduce to only the necessary constructors.
15-15
: Provide a test or commentary for the(example ...)
invocation.
If(fail (l))
is designed to trigger an error, consider explaining how this example is verified (e.g., via a golden file or an automated test).examples/non-examples/stack-traces/error-in-constructor.kl (3)
5-7
: Evaluate necessity of Pair type in this demo.
If you only need thepair
constructor for an error demonstration, consider referencing a simpler or pre-existing type to keep this example self-contained. Alternatively, add clarity on why a new type is introduced.
8-11
: Add an inline comment explaining how fst is tested.
Given that this example focuses on error handling forfail
, clarify thatfst
is a utility. Document or reference where its behavior is validated.
20-20
: Consider expanded testing for(fail 23)
.
If this example is meant to produce a deterministic error trace, add explanation or a golden file capturing the exact stack trace. This ensures clarity and consistency in the demonstration.Would you like me to provide a script or snippet that checks for a matching error message in your golden file tests?
examples/non-examples/stack-traces/error-in-bind-tail.kl (2)
4-6
: Potential mismatch with thesyntax-error
usage.Within a monadic setting, calling
(syntax-error x)
directly in the continuation may not always yield the desired effect. Depending on howsyntax-error
is implemented, it could short-circuit the evaluation or trigger an upstream macro expansion issue.If you’d like, I can investigate how
syntax-error
behaves under monadic bindings by searching for its definition or usage across the codebase. Let me know if you want me to open a GitHub issue or propose a direct fix.
7-7
: Clarify the TODO.It appears the TODO comment is asking why
(syntax-error x)
does not propagate as expected. Capturing or clarifying that logic may involve analyzing the macro expansion flow or ensuring the error is thrown in the correct phase.I can assist by walking through the expansion phases or verifying the macro expansion to confirm if
(syntax-error x)
is correctly recognized. Let me know if that’s helpful.src/Debugger.hs (2)
1-22
: Consider documenting module usage and error-handling model.You've introduced a brand-new debugger module and monad but haven't provided high-level documentation for how end-users, or other contributors, should utilize it. Consider adding a top-level Haddock comment or README references discussing:
• The typical usage pattern ofDebug r e a
.
• How errors are meant to be surfaced (viadebug
,catch
, etc.).
• Basic examples or recommended best practices.
103-112
: Consider including stack tracing details indebug
.Your
MonadDebugger
implementation logs errors usingdebug e
, but does not appear to attach any additional context like location, call site, or partial state. Including more contextual details can drastically improve debugging experience, especially for advanced use-cases.src/Expander/TC.hs (8)
36-36
: Check for additional error context.debug $ InternalError "Dangling type metavar"
While this is a valid usage, consider providing more context (e.g., which type metavar is dangling) to make errors more actionable.
82-82
: Verify the correctness of occurs-check error.debug $ TypeCheckError $ OccursCheckFailed ptr t'
Ensure the
ptr
and the normalizedt'
are enough to diagnose the exact nature of the failed occurs-check. You might want location data or more descriptive text for better debugging.
113-113
: Potential mismatch error detail.debug $ InternalError "Mismatch in number of type vars"
If possible, include the expected vs. actual counts for clarity, preventing confusion for future maintainers and users.
198-198
: Clarify generalization error.debug $ InternalError "Can't generalize in scheme"
It's unclear why the code can't generalize here. Consider specifying the cause or the relevant scheme pointer to enhance debugging.
292-296
: Include deeper type mismatch context if possible.debug $ TypeCheckError $ TypeMismatch loc e' r' Nothing ... debug $ TypeCheckError $ TypeMismatch loc outerE' outerR' (Just (e', r'))
These error sites are crucial. If there's a possibility to retrieve surrounding type context or call site, it may improve support for diagnosing tricky type mismatches.
305-305
: Add pointer reference to "Type variable not found!"debug $ InternalError "Type variable not found!"
Consider including the missing pointer or relevant state. This can greatly reduce time to locate issues in large expansions.
327-327
: Clarify kind mismatch.debug $ KindMismatch loc k1' k2'
If you can, include more context or potential resolution steps in the error message. For instance, mention which type or constructor triggered the mismatch.
381-381
: Consider alternative approach.debug $ InternalError "Tried to find kind in open context"
If this scenario arises frequently, you may want to unify or infer the kind more gracefully rather than throwing an internal error. Evaluate if there's a legitimate fallback or partial solution.
src/Evaluator.hs (2)
162-169
: Enhance documentation for new constructors.InCasePattern InDataCasePattern
You've introduced these pattern-specific constructors to track matched patterns in the stack trace. Ensure test coverage includes scenarios in which these new constructors appear, verifying correct debugging output.
703-706
: GuardprojectError
usage carefully.projectError (Er err _env _kont) = err projectError _ = error "projectError not used on an error!"
Accidentally calling
projectError
on a non-error state raises an exception. ConsiderEither
or safer checks to avoid runtime crashes in unforeseen situations.src/Pretty.hs (4)
5-5
: EnsureLambdaCase
extension usage is minimal.Using
LambdaCase
can improve conciseness, but if used heavily, it may reduce readability for some developers. Make sure usage is consistent and documented to keep code approachable.
113-114
: Refine let-binding layout.hang 2 $ vsep [ text "let" <+> hang 2 ...
While
hang
andvsep
produce readable blocks, test against deeply nested structures or large let blocks to ensure it doesn't become unwieldy. You might prefer usinggroup
or more advanced layout combinators for large expressions.
368-372
: Tailor function arrow printing.(TyF TFun [a, b]) -> ...
Here, you print the function arrow in a multi-line format. Verify this remains legible in large, curried function types. Some teams prefer single-line for short types, and multiline only when needed. Possibly consider
group
to handle multi-line gracefully.
810-812
: Consider partial expansions for macros.(InBindMacroTl action _env k) -> ...
Highlight partial expansions or placeholders in logs. If macros are partially expanded, having a marker in the final pretty print might help.
src/Expander/Monad.hs (9)
599-599
: Investigate incomplete module.Nothing -> debug $ InternalError "Incomplete module after expansion"
You might want a reference to
ptr
or module name for more clarity, helping identify which module is incomplete.
610-610
: Missing decl detail.Nothing -> debug $ InternalError "Missing decl after expansion"
Likewise, consider specifying the pointer or the expected declaration name for faster troubleshooting.
619-623
: Missing expr or scheme references.Nothing -> debug $ InternalError "Missing expr after expansion" ... Nothing -> debug $ InternalError "Missing scheme after expansion"
In each of these checks, incorporate the missing pointers or user-located code snippet references.
632-632
: Enhance define macros message.Nothing -> debug $ InternalError "Missing expr after expansion"
DefineMacros
might be trickier to debug if you have no info about which macro is missing. Consider including the macro’s name or pointer ID.
648-648
: Adding pointer detail for missing types.debug $ InternalError "Missing type after expansion"
If you have a pointer or constructor name, it would be an excellent reference in the error to help locate which type was lost.
668-668
: Missing action detail.debug $ InternalError "Missing action after expansion"
Similar to other missing expansions, referencing the pointer or call site helps track down the culprit.
785-785
: Likewise for unknown datatype.debug $ InternalError $ "Unknown datatype " ++ show datatype
Same principle: referencing the unknown entity is helpful. Confirm that any place you look up this
datatype
includes relevant phase or module context if multi-phase expansions are possible.
851-851
: Preventing stuck expansions.debug (NoProgress (map (view _3) remainingTasks))
Ensure that each
NoProgress
case is properly tested, and the user receives enough info to fix the stuck expansions. Possibly indicate the tasks themselves or current environment state.
867-870
: Distinguishing macro evaluation failures.case evaluateIn env evalAction of Left e_state -> debug $ MacroEvaluationError p e_state Right val -> return val
Differentiate macro runtime errors from type or resolution issues if possible. This helps end-users identify macro-level logic errors vs. type mismatch expansions.
examples/non-examples/stack-traces/error-in-list.kl (2)
9-9
: Rename the function for clarity or confirm its intended semantics.
fail
is misleading since it doesn't fail but instead increments its argument. Choose a more descriptive name such asincrement
or confirm that this is essentially a "fail" for test scenarios.
11-12
: Add tests to validatefail
and error usage.A TODO remains regarding testing. Consider verifying that
(fail the-error)
indeed produces an appropriate error scenario, and that(fail thing)
gives the expected numeric result ifthing
is numeric.src/StackTraces.hs (3)
29-32
: Add environment context to printed error messages.
printStack
prints the error but doesn't show contextual details about the environment or continuation. Consider includingprintEnv env
or relevant details fromprintKont k
to make debugging more thorough.
33-35
: Add descriptive comments for complex continuations.Although
printKont
uses alignment and vertical separation, it's not immediately clear how complex continuations are displayed. A comment or docstring explaining the structure of the printed output would be beneficial.
39-40
: Consider additional environment details inprintEnv
.
printEnv
uses default pretty-printing. Evaluate whether you want more context (e.g., variable name-value pairs) in the output for debugging complex scenarios.repl/Main.hs (1)
150-150
: Potential Enhancement for Error Reporting
Currently,evalErr
is printed directly. Consider providing more structured error information (e.g., stack traces or REPL hints) if the user is meant to debug runtime errors in-depth.src/Expander/Syntax.hs (2)
18-18
: Debugger Import
ImportingDebugger
indicates an intent to shift from throwing errors to logging or debugging. Ensure consistent usage ofdebug
across this module and that there's no leftoverthrowError
.
60-60
: Import Error for Modules
Returningdebug (ImportError err)
can help track modules not found. Consider logging the actual file path to aid debugging.src/Expander/Error.hs (6)
128-128
:NotEmpty
Pretty Printer
Replacing old code withhang 2 $ vsep [...]
. Keep consistent indentation for clarity in the final output.
136-136
:NotInteger
Retain example or context in error messages for user clarity if possible.
141-141
:NotString
Same comment as above—string literal info might help.
192-192
:ValueNotSyntax
Consider logging what the actual value was for deeper insights.
218-218
:NotValidType
If there's a partial explanation for why it's invalid, consider adding it to the error.
241-242
:CircularImports
Just ensure that any large cycles produce manageable error logs.Would you like me to propose a limit on the depth or size of displayed cycles?
src/Expander.hs (2)
Line range hint
1392-1392
: Address TODO for error message in module body handling.There's a TODO comment for implementing a proper error message for malformed module bodies.
Would you like me to help implement a proper error message for malformed module bodies? I can suggest an implementation or create a GitHub issue to track this task.
Line range hint
1-1447
: Consider implementing a centralized error handling strategy.The codebase would benefit from a more systematic approach to error handling. Consider:
- Creating an error type hierarchy that covers all possible error cases
- Implementing a centralized error handling mechanism
- Using smart constructors for error creation to ensure consistency
- Adding error context information for better debugging
This would improve the consistency of error handling and make the stack traces more useful.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (78)
examples/ambiguous-kind.golden
(1 hunks)examples/bound-identifier.golden
(1 hunks)examples/contract.golden
(1 hunks)examples/datatype-macro.golden
(1 hunks)examples/datatypes.golden
(1 hunks)examples/defun-test.golden
(1 hunks)examples/error.golden
(1 hunks)examples/eta-case.golden
(1 hunks)examples/failing-examples/bound-vs-free.golden
(1 hunks)examples/failing-examples/incorrect-context.golden
(1 hunks)examples/failing-examples/keyword-used-incorrectly.golden
(1 hunks)examples/failing-examples/wrong-keyword.golden
(1 hunks)examples/fix.golden
(1 hunks)examples/hygiene.golden
(1 hunks)examples/import-scoping.golden
(1 hunks)examples/import.golden
(1 hunks)examples/lambda-case-test.golden
(1 hunks)examples/lang.golden
(1 hunks)examples/let.golden
(1 hunks)examples/lets.golden
(1 hunks)examples/list-syntax.golden
(1 hunks)examples/list-test.golden
(1 hunks)examples/meta-macro.golden
(1 hunks)examples/monad.golden
(1 hunks)examples/non-examples/bad-lexical-env.golden
(1 hunks)examples/non-examples/bad-lexical-env.kl
(1 hunks)examples/non-examples/circular-1.golden
(1 hunks)examples/non-examples/circular-2.golden
(1 hunks)examples/non-examples/error.golden
(1 hunks)examples/non-examples/import-phase.golden
(1 hunks)examples/non-examples/missing-import.golden
(1 hunks)examples/non-examples/stack-traces/.#error-in-cons-head.golden
(1 hunks)examples/non-examples/stack-traces/error-in-arg.golden
(1 hunks)examples/non-examples/stack-traces/error-in-arg.kl
(1 hunks)examples/non-examples/stack-traces/error-in-bind-head.golden
(1 hunks)examples/non-examples/stack-traces/error-in-bind-head.kl
(1 hunks)examples/non-examples/stack-traces/error-in-bind-tail.golden
(1 hunks)examples/non-examples/stack-traces/error-in-bind-tail.kl
(1 hunks)examples/non-examples/stack-traces/error-in-case-constructor.golden
(1 hunks)examples/non-examples/stack-traces/error-in-case-constructor.kl
(1 hunks)examples/non-examples/stack-traces/error-in-cons-head.golden
(1 hunks)examples/non-examples/stack-traces/error-in-cons-head.kl
(1 hunks)examples/non-examples/stack-traces/error-in-constructor.golden
(1 hunks)examples/non-examples/stack-traces/error-in-constructor.kl
(1 hunks)examples/non-examples/stack-traces/error-in-let.golden
(1 hunks)examples/non-examples/stack-traces/error-in-let.kl
(1 hunks)examples/non-examples/stack-traces/error-in-list.golden
(1 hunks)examples/non-examples/stack-traces/error-in-list.kl
(1 hunks)examples/non-examples/stack-traces/error-in-pure-macro.golden
(1 hunks)examples/non-examples/stack-traces/error-in-pure-macro.kl
(1 hunks)examples/non-examples/stack-traces/in-arg-error.golden
(1 hunks)examples/non-examples/stack-traces/in-arg-error.kl
(1 hunks)examples/non-examples/type-errors.golden
(1 hunks)examples/pmatch.golden
(1 hunks)examples/prelude-test.golden
(1 hunks)examples/primitives-documentation.golden
(2 hunks)examples/product-type.golden
(1 hunks)examples/quasiquote-syntax-test.golden
(1 hunks)examples/syntax-loc.golden
(1 hunks)examples/temporaries-test.golden
(1 hunks)examples/test-quasiquote.golden
(1 hunks)examples/tiny-types.golden
(1 hunks)examples/two-defs.golden
(1 hunks)examples/unknown-type.golden
(1 hunks)examples/which-problem.golden
(1 hunks)flake.nix
(2 hunks)klister.cabal
(2 hunks)repl/Main.hs
(3 hunks)src/Debugger.hs
(1 hunks)src/Evaluator.hs
(10 hunks)src/Expander.hs
(26 hunks)src/Expander/Error.hs
(7 hunks)src/Expander/Monad.hs
(13 hunks)src/Expander/Primitives.hs
(5 hunks)src/Expander/Syntax.hs
(6 hunks)src/Expander/TC.hs
(9 hunks)src/Pretty.hs
(22 hunks)src/StackTraces.hs
(1 hunks)
✅ Files skipped from review due to trivial changes (40)
- examples/non-examples/circular-2.golden
- examples/failing-examples/wrong-keyword.golden
- examples/bound-identifier.golden
- examples/non-examples/circular-1.golden
- examples/lang.golden
- examples/failing-examples/incorrect-context.golden
- examples/non-examples/import-phase.golden
- examples/temporaries-test.golden
- examples/lets.golden
- examples/non-examples/missing-import.golden
- examples/non-examples/type-errors.golden
- examples/non-examples/bad-lexical-env.golden
- examples/eta-case.golden
- examples/failing-examples/keyword-used-incorrectly.golden
- examples/lambda-case-test.golden
- examples/two-defs.golden
- examples/datatype-macro.golden
- examples/error.golden
- examples/ambiguous-kind.golden
- examples/fix.golden
- examples/contract.golden
- examples/pmatch.golden
- examples/let.golden
- examples/defun-test.golden
- examples/failing-examples/bound-vs-free.golden
- examples/prelude-test.golden
- examples/list-test.golden
- examples/syntax-loc.golden
- examples/import-scoping.golden
- examples/quasiquote-syntax-test.golden
- examples/import.golden
- examples/meta-macro.golden
- examples/product-type.golden
- examples/hygiene.golden
- examples/list-syntax.golden
- examples/test-quasiquote.golden
- examples/datatypes.golden
- examples/monad.golden
- examples/which-problem.golden
- examples/unknown-type.golden
🔇 Additional comments (90)
examples/non-examples/bad-lexical-env.kl (2)
3-3
: Potentially undefined variabley
.Inside the function
f
, the variabley
is referenced but never defined in this scope or in a surrounding scope, which may produce a lexical error unless intentionally used to demonstrate the environment error mechanic. Verify that you indeed intend to reference a free variable here for testing or demonstration.
4-4
: No argument passed tof
.The function
g
callsf
without passing any arguments, despitef
having a parameter(ff)
. If this is intentional for error demonstration, it’s fine, but otherwise consider supplying the needed argument to avoid runtime errors.examples/tiny-types.golden (2)
10-11
: Clear separation of annotations and identifiers
Moving<a>
to a separate line makes the code structure more readable. This is a valuable improvement.
12-13
: Good formatting clarification for free identifier<b>
Separating<b>
onto its own line improves readability, matching the adjustments made for<a>
. Nicely done!examples/primitives-documentation.golden (5)
29-30
: Good separation of type variables to improve readability.
The new multiline format forpure-IO
’s signature is clear and accurately expresses the type relationship.
45-46
: No issues detected with thenothing
signature.
This multiline formatting is consistent and improves clarity.
47-48
:nil
signature is clearly expressed.
No functional or stylistic concerns; this line break pattern matches the rest of the file.
51-52
:id
signature is well-formatted.
No change to logic; looks good as is.
56-59
:compose
signature refactor is clear and readable.
Breaking out each type variable on its own line is understandable, but ensure it’s consistently applied throughout the file for clarity.examples/non-examples/stack-traces/error-in-pure-macro.kl (1)
1-3
: Validate that the example effectively demonstrates the error scenario.
The example sets up a pure macro that triggers an error, which is good for ensuring that error handling logic is tested. Verify that any upstream or downstream code referencing this file treats the error as expected.examples/non-examples/stack-traces/in-arg-error.golden (1)
1-6
: Good clarity and specificity in the error message.
The mismatch details are clearly itemized by showing the expected and actual types. This approach aids rapid debugging. If needed, consider unifying message formats project-wide for consistency.examples/non-examples/stack-traces/error-in-arg.kl (3)
1-2
: Consistent language specification.
The usage of#lang "prelude.kl"
is in line with the existing examples, so no changes are needed here.
3-3
: Validate numeric input for(fail)
.
The function assumesthing
is numeric. In tests or higher-level logic, ensure that calling(fail)
with a non-numeric argument either raises a clear error or is validated beforehand.
5-5
: Intentional error example looks good.
Invoking(error 'bad)
is a useful demonstration for stack-trace behavior. No changes required.examples/non-examples/stack-traces/error-in-list.golden (1)
1-5
: Clear and concise error message format.
This new format provides a straightforward location reference, an error description, and a stack trace. It’s consistent and easy to follow. No issues found.examples/non-examples/stack-traces/in-arg-error.kl (3)
1-2
: Language specification confirmed.
The file correctly uses#lang "prelude.kl"
. No changes needed here.
3-3
: Check numeric assumption for(fail)
.
As with the other example, confirm thatsomething
is numeric or handle invalid input gracefully.
5-5
: Error scenario is properly illustrated.
This line shows the function raising an error to demonstrate stack-trace handling. Good for testing.examples/non-examples/stack-traces/error-in-arg.golden (1)
1-6
: Structured error format looks consistent.The newly introduced error message and stack trace align with the improved style described in the PR objectives. This should help users quickly locate and diagnose the issue in
error-in-arg.kl
.examples/non-examples/stack-traces/error-in-pure-macro.golden (1)
1-6
: Good consistency in error framing.This example’s error output provides a clear message and a concise stack trace for a pure macro. Keeping a uniform style across all .golden files will aid debugging and maintain clarity.
examples/non-examples/stack-traces/error-in-case-constructor.golden (1)
1-6
: Clear presentation of case-constructor error.This error and stack trace demonstrate a consistent style with the other .golden files. No further issues spotted.
examples/non-examples/stack-traces/error-in-let.kl (1)
1-7
: Example snippet successfully demonstrates the error mechanism.The snippet correctly illustrates the behavior of throwing an error and halting the program flow. This is useful for verifying that the new stack trace enhancements are working as intended.
examples/non-examples/stack-traces/error-in-bind-head.golden (1)
1-9
: Please verify accuracy of error references.The error message and stack trace are clearly structured. However, ensure that the file reference
error-in-bind-head.kl:3.29-3.30
aligns precisely with the location of the failing expression.examples/non-examples/stack-traces/error-in-let.golden (1)
1-8
: Maintain consistent error references.This new structured error output is aligned with other error reporting. As a suggestion, verify the file and line references (
error-in-let.kl:4.42-4.53
and#[error-in-let.kl:4.22-4.24]
) to ensure their accuracy in pointing to the offending code.examples/non-examples/stack-traces/error-in-constructor.golden (1)
1-9
: Confirm constructor location and field references.The detailed stack trace is helpful. Double-check that the error location
error-in-constructor.kl:17.45-17.56
and field index “2” in the constructorpair
are indeed correct. Inconsistencies in trace indexing can cause confusion.examples/non-examples/stack-traces/error-in-case-constructor.kl (1)
9-13
: Confirm the handling of(else the-other)
.
the-other
isn't defined in this snippet, implying it's either an unbound symbol or intentionally a placeholder. If it's a placeholder, consider naming it more clearly or documenting it for clarity.examples/non-examples/stack-traces/error-in-constructor.kl (1)
16-18
: Double-check the error strategy infail
.
Here,fail
constructs a pair whose second element is always an error. If the goal is to illustrate a stack trace at construction, that’s fine; otherwise, consider deferring the error until the pair is accessed.examples/non-examples/stack-traces/error-in-bind-tail.golden (1)
1-5
: Good addition to illustrate the error scenario in binding tails.This golden file snippet effectively demonstrates how an error is triggered and traced in the binding tail of a macro scenario. It’s helpful to see the exact points in the code (
#[error-in-bind-tail.kl:4.15-4.28]
) where the failure occurs, aiding debugging and clarifying the error context. No issues detected; the changes are aligned with the PR’s goal of improving stack trace outputs.examples/non-examples/stack-traces/error-in-bind-tail.kl (2)
1-3
: Solid demonstration setup for error handling tests.The inclusion of a
prelude.kl
language mode and the(example ...)
construct is appropriate for testing macro-related errors in a controlled manner. This ensures coverage for the tail-binding scenario referenced in the.golden
file.
8-8
: Neat final bind.Returning
(pure y)
ensures the final result is well-formed if no error is triggered. Coupled with the preceding monadic steps, this lines up with the stated goals of testing stack traces and error handling in a tail-binding scenario.src/Debugger.hs (2)
45-47
: Confirm thatdebugRunT
is consistent with your monad design.While
debugRunT
simply flipsrunDebug
, ensure that all code paths call it appropriately. If other modules expect a function with the signaturer -> Debug r e a -> IO (Either e a)
, confirm consistency so that you don’t inadvertently cause confusion when wrapping or unwrapping therunDebug
function.
50-51
: Validate themapDebugT
transformation.The function composes
fmap
andsecond
, suggesting transformation of both left (error) and right (value) sides. Verify that the intent is indeed to allow transformations of the successful result while preserving the error. If, for any reason, you need to transform the error side as well, you might consider a more comprehensive approach to mapping both sides of theEither
.src/Expander/TC.hs (1)
20-20
: Import check.The added
import Debugger
is consistent with your broader shift toward using theDebug
monad. Ensure all references to the old error-handling approach (if any remain) are removed to avoid confusion.src/Evaluator.hs (2)
256-258
: Confirm that mediator logic is correct.(InCasePattern _ kont) -> Up v e kont (InDataCasePattern _ kont) -> Up v e kont
You’re passing the value
v
up with no additional transformation or pattern checks. Confirm that skipping further case analysis (beyond capturing the pattern in the continuation) is intended behavior; if so, it makes sense, but you might want explicit docstrings explaining why no additional evaluation is needed here.✅ Verification successful
Let me gather more information about the case pattern handling in the evaluator.
The mediator logic for case patterns is correct and well-documented
The behavior is intentionally designed this way, as explained in the
Note [InCasePattern]
comment found in the codebase:In case pattern is strictly not necessary, we could do this evaluation in the host's runtime instead of in the evaluator but doing so would mean that the debugger would not be able to capture the pattern that was matched.
The pattern matching and environment setup is actually done before reaching these continuation handlers, as evidenced by the
match
function calls where:
- The environment is properly extended with matched values
- The pattern is stored in the continuation for debugging purposes
- The continuation handlers (
InCasePattern
andInDataCasePattern
) simply pass the value up after the match is completeThis design ensures that the debugger can track which patterns were matched while keeping the actual pattern handling logic clean and efficient.
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for InCasePattern and InDataCasePattern definitions and usages ast-grep --pattern 'data $_ = InCasePattern $$ | InDataCasePattern $$' # Look for comments or documentation about case pattern handling rg -B 2 -A 2 "InCasePattern|InDataCasePattern" # Search for Note about InCasePattern rg "\[InCasePattern\]"Length of output: 4429
707-710
: Potential utility in partial states.projectKont (Er _ _ k) = k projectKont (Up _ _ k) = k projectKont (Down _ _ k) = k
Similar to
projectError
, ensure that usage in partial states won't lead to misinterpretation. If other code might rely on the presence of a particular value in the continuation, consider clarifying the usage contract in docstrings.✅ Verification successful
Let me gather more information about the usage of
projectKont
and related functions to verify the concern.
Let me search for more context about the EState type and its usage.
Based on the gathered information, I can now provide the final response:
projectKont
is safely used in partial statesThe codebase shows that
EState
is a well-defined sum type with three constructors (Down
,Up
, andEr
), each carrying a continuation (Kont
) as their last parameter. TheprojectKont
function is implemented correctly for all three constructors, and its usage pattern is consistent with the evaluation model:
- The evaluation step function (
step
) handles all three states appropriately- The continuation is consistently used across state transitions
- Error states (
Er
) preserve the continuation for proper error handling and stack traces- The function is used in conjunction with
projectError
for error reporting🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for projectKont usage and implementation rg "projectKont" -A 3 # Search for EState type definition and related types ast-grep --pattern 'data EState = $_' # Look for similar projection functions rg "project.*\s*::\s*EState" -A 2 # Search for functions that use the continuation (k) rg "k\s*=\s*projectKont" -A 3Length of output: 794
Script:
#!/bin/bash # Search for EState data type definition rg "data EState" -A 10 # Search for Kont type definition rg "type Kont" -A 3 # Search for functions that construct EState values rg "Er\s+|Up\s+|Down\s+" --type haskell -A 2 # Look for functions that pattern match on EState ast-grep --pattern 'case $_ of Er $$ -> $$ Up $$ -> $$ Down $$ -> $$'Length of output: 16311
src/Pretty.hs (2)
697-698
: Validate new EState pretty-print approach.instance Pretty VarInfo EState where pp env st = printStack env st
Make sure that
printStack
provides enough detail about the CEK machine state for typical debugging. If users often need more detail, you might consider more granular or layered printing options.
74-80
: Check for layout configuration consistency.pretty x = renderStrict (layoutSmart defaultLayoutOptions (pp Env.empty x)) prettyPrint x = putDocW 80 (pp Env.empty x) prettyPrintLn x = putDocW 80 (pp Env.empty x) >> putStrLn ""
You're using a mix of
layoutSmart
andputDocW 80
. Verify the chosen layout width aligns with your team’s style guidelines and remains consistent across all pretty-print calls.✅ Verification successful
Let me gather information about the layout configuration usage across the codebase.
Let me search for any configuration files or constants that might define layout settings.
Let me check the entire Pretty.hs file to understand the complete context of pretty printing usage.
Layout configuration is consistently used across pretty-printing functions
After analyzing the codebase, I can confirm that the mix of
layoutSmart
andputDocW 80
is intentional and correct:
pretty
function useslayoutSmart defaultLayoutOptions
because it's for rendering toText
, where smart layout decisions are beneficial for the output formatprettyPrint
andprettyPrintLn
useputDocW 80
because they're specifically for terminal output where a fixed width of 80 columns is a standard conventionThe layout configuration is consistent with their respective purposes:
- Text rendering: Smart layout for flexible output
- Terminal output: Fixed 80-column width for readability
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for layoutSmart and defaultLayoutOptions usage rg "layoutSmart|defaultLayoutOptions" -A 2 # Search for putDocW usage to check layout width configurations rg "putDocW" -A 2 # Search for any other pretty printing related configuration rg "layoutOptions|pageWidth" -A 2Length of output: 862
Script:
#!/bin/bash # Search for any layout-related constants or configurations rg -g '!*.lock' -g '!dist*' "pageWidth|layoutWidth|lineWidth|columns" -A 2 # Look for any pretty-printing related configuration files fd -e yaml -e toml -e json -e conf -e config . | xargs rg "layout|pretty|print|width" # Search for any module that might contain pretty-printing configurations fd "Pretty|Format|Layout" -t fLength of output: 211
Script:
#!/bin/bash # Get the complete content of Pretty.hs cat src/Pretty.hsLength of output: 28201
src/Expander/Monad.hs (4)
177-177
: Confirm removal of legacy error handling.import Debugger
Now that you're pulling in
Debugger
, ensure any leftover references toExceptT
orthrowError
are replaced throughout. Mixed usage can lead to confusion during expansions.
775-775
: Unknown constructor.debug $ InternalError $ "Unknown constructor " ++ show ctor
This is more descriptive. Good job including the failing constructor's name. Ensure coverage for datatypes as well.
929-929
: Handling circular imports.debug $ CircularImports ...
You do mention how the cycle is composed. Good job. Ensure it’s easy for a user to see the chain of modules. Possibly advise a fix or an alternate approach to break the cycle.
208-212
: Check monad transformer stacking.newtype Expand a = Expand { runExpand :: ReaderT ExpanderContext (Debug DebugContext ExpansionErr) a } deriving (Functor, Applicative, Monad, MonadIO, MonadDebugger ExpansionErr, MonadReader ExpanderContext)
This is a significant shift to
Debug
. Validate that all places formerly relying onMonadError
semantics now handle or interpretExpansionErr
viadebug
.✅ Verification successful
Let me gather information about the usage of
MonadError
andDebug
in the codebase.
Let me search for more specific error handling patterns to understand how errors are handled in the codebase.
Based on the gathered information, I can now provide the final response:
The shift to
Debug
monad is properly handled withMonadDebugger
instancesThe codebase has been properly adapted to use the
Debug
monad transformer through theMonadDebugger
typeclass. The key findings show:
- All error handling previously done through
MonadError
has been systematically replaced withMonadDebugger
'sdebug
andcatch
operations.- The
Expand
monad correctly derivesMonadDebugger ExpansionErr
instance, ensuring proper error handling throughout the expander.- Error propagation is consistently handled via the
Debug
monad's semantics, with proper instances for transformer stacks (Reader, State).- The codebase shows systematic use of
debug
for error reporting across all expansion-related modules (Expander.Syntax, Expander.TC, etc.).🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for MonadError usage rg "MonadError" -A 3 # Search for Debug type and its usage rg "Debug\s+\w+\s+\w+" -A 3 # Search for ExpansionErr rg "ExpansionErr" -A 3 # Look for error handling patterns ast-grep --pattern 'throwError $_'Length of output: 4753
Script:
#!/bin/bash # Search for debug error handling patterns rg "debug\s+" -A 3 # Search for catch usage rg "catch\s+" -A 3 # Look for MonadDebugger type class definition ast-grep --pattern 'class MonadDebugger' # Search for error handling in Expand monad rg "Expand.*Error" -A 3Length of output: 24368
examples/non-examples/stack-traces/error-in-list.kl (1)
7-7
: Ensure appropriate handling when calling(fail the-error)
.
the-error
is a symbolic error object, whilefail
expects a numeric argument. This will likely result in an error if these are combined at runtime. Consider adding type checks or clarifying usage to avoid unexpected failures.src/StackTraces.hs (1)
36-37
: Ensure allEvalError
variants are displayed consistently.
printErr
usespretty
, but someEvalError
variants might need specialized formatting to provide optimal troubleshooting information. Verify that these variants are handled as intended.flake.nix (2)
24-24
: Confirm thatcabal-install
is necessary in all development scenarios.Including
cabal-install
may be desirable for local builds. Ensure that the rest of the team also installs or uses it consistently to avoid environment disparities.
55-57
: Validate the KLISTERPATH environment variable.Setting
KLISTERPATH
toexamples/
helps with local testing but may need refinement if code examples or tests exist in other directories. Confirm the correct path to ensure all examples are found.klister.cabal (1)
63-63
: AddingDebugger
as an exposed module looks good.This new module is properly declared and consistent with the rest of the code changes aimed at improving error handling and debug support.
repl/Main.hs (4)
36-36
: Encapsulation Benefit fromnewtype
SwitchingOptions
to anewtype
is a good practice, providing a more transparent type at runtime while maintaining a clear separation at the type level. This helps avoid accidental misuse of the underlying constructor.
37-38
: Addition ofrunOptBindingInfo
The new boolean fieldrunOptBindingInfo
should be tested to verify its impact. If its usage influences output conditionally, ensure there's a test covering that path.
41-41
: Consistency in Usingnewtype ReplOptions
Usingnewtype
forReplOptions
improves type safety and consistency withOptions
.
66-67
: Subcommand Parser Readability
The parser updates increase readability by removing extra parentheses. Ensure help text and usage messages remain accurate for the "run" and "repl" commands.src/Expander/Syntax.hs (15)
6-6
:TypeOperators
Language Extension
EnablingTypeOperators
here is common for more advanced type-level constructs. Confirm there's a team-wide agreement on using these language extensions for broad consistency.
28-28
: Use ofdebug (NotIdentifier other)
Replacing error throws with debug calls avoids immediate failure but might degrade discoverability of certain logic mistakes. Review downstream usage to ensure essential errors still surface properly.
32-32
: Empty List Check
debug (NotEmpty other)
clarifies an expected shape. Double-check that any code relying on the older thrown exception pattern is updated to handle the new debug approach.
36-36
: Cons Check
debug (NotCons other)
fits the pattern for logging errors in Syntax checks. Ensure the user or developer receives appropriate feedback when syntax is invalid.
40-40
: Cons-Cons Check
debug (NotConsCons other)
is consistent with the new debugging approach. Confirm that the build or test suite covers scenarios that trigger this message.
45-45
: List Check
debug (NotList other)
—similarly be sure this debug message is tested so real syntax mistakes become discoverable.
49-49
: Integer Check
debug (NotInteger other)
might obscure type-level errors if not tested. Consider a test covering non-integer inputs.
53-53
: String Check
debug (NotString other)
continues the same logging approach. Keep consistency for user-facing messages.
65-65
: Not a Module Name
debug (NotModName other)
—the user might need to see the invalid name in context. Double-check that the diagnostic includes a helpful snippet.
78-78
: List Length Error
debug (NotRightLength lengths stx)
—helpful for understanding mismatched macro patterns. Ensure tests exist for multiple valid lengths.
80-80
: Not a List
debug (NotList other)
triggered if the shape is not aList
at all. Same checks about coverage apply.
145-146
:mustHaveShape
for Empty
debug (NotEmpty other)
anddebug (NotList other)
replaced older error approach. Please confirm call sites that rely on a thrown error are updated.
157-158
:mustHaveShape
for Pairs
debug (NotCons other)
anddebug (NotList other)
—similar note on verifying code that depends on the older approach.
167-167
:mustHaveShape
for Lists
debug (NotList other)
might cause silent debugging logs if unhandled. Confirm there's an integration test for this scenario.
Line range hint
691-691
:UnknownPattern
debug (UnknownPattern other)
replaces a thrown error. Ensure there's a mechanism to handle unknown patterns gracefully or fail fast if needed in production.src/Expander/Error.hs (20)
3-3
:LambdaCase
Extension
EnablingLambdaCase
is consistent with the rest of the codebase. No issues noted.
54-55
:MacroEvaluationError
&ValueNotMacro
Switching toEState
ties them more closely to the new debugging framework. This can help track evaluation context in logs. Confirm all references to old error types are updated.
130-130
:NotCons
Pretty Printer
Good alignment with the new debugging phrasing.
132-132
:NotConsCons
All good. No suggestions beyond verifying final error string.
134-134
:NotList
Pretty Printer
Clearer error messages are beneficial.
146-146
:NotModName
Ensuring the expected module name gets clarified in error. Looks good.
151-151
:NotRightLength
Thealts
function is a neat approach to handle multiple expected lengths. The error text is user-friendly.
166-166
:NotVec
Indicates an expectation for square-bracketed syntax. The error message is now consistent with otherNot*
style messages.
168-168
:NotImportSpec
No concerns. The code is consistent with the new style.
170-170
:NotExportSpec
Same note as above regarding consistency.
172-172
:UnknownPattern
Ensures that unrecognized patterns become a known debugging scenario.
177-177
:MacroRaisedSyntaxError
Displaying additional locations is helpful. Make sure there's no performance overhead if the location list grows large.
186-186
:MacroEvaluationError
Now referencesEState
. This design fits the new debugging approach well.
196-196
:NotExported
It’s good you’re including the phase in the message. Ensure the location is well formatted for large codebases.
205-205
:WrongSyntacticCategory
The structure is more streamlined.
207-211
: Neat Separation of Expected vs. Supported
The use of hinges (hang
) +vsep
for multi-line output is a nice improvement for error readability.
228-228
:NotAConstructor
Error text for constructor mismatch is consistent with the new style.
236-238
:KindMismatch
Usingmaybe (text "unknown location") ...
elegantly handles possible missing source locations.
246-263
:TypeMismatch
Good to see the more explicit detail in the error message. The “Specifically” block helps highlight submismatches.
269-270
:OccursCheckFailed
The error text is direct, describing the pointer and type. All good.src/Expander/Primitives.hs (4)
76-76
: Debugger Import
Consistent with the rest of the codebase’s shift to debugging.
522-522
:WrongTypeArity
Handling
Usingdebug
ensures the code logs an error rather than raising an exception. Confirm that calling code can proceed gracefully if the arity is wrong.
534-534
: PatternedWrongTypeArity
Again, ensure that shifting from a thrown error to a debug call does not break any expected short-circuit behavior.
592-592
:NotValidType
inmakeLocalType
Previously, an invalid type might raise an exception. Now it's logged viadebug
. Double-check any dependent logic that might assume an exception.src/Expander.hs (1)
61-61
: LGTM! New import aligns with PR objectives.The addition of the
Debugger
import supports the transition to improved stack trace functionality.
instance Monad (Debug r e) where | ||
Debug m >>= f = Debug $ \r -> do | ||
ma <- m r | ||
case ma of | ||
Left err -> return (Left err) | ||
Right val -> fmap (debugRunT r) f val | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential issue in Monad (Debug r e)
bind.
Debug m >>= f = Debug $ \r -> do
ma <- m r
case ma of
Left err -> return (Left err)
Right val -> fmap (debugRunT r) f val
This snippet uses fmap (debugRunT r) f val
, which looks suspicious and might not apply the function f val
in the usual monadic style. It's typically f val
→ some Debug r e b
, and then you'd call runDebug (f val) r
. Double-check the logic to ensure you properly chain monadic computations.
let ppPattern = \case | ||
SyntaxPatternIdentifier i _ -> pp e i | ||
SyntaxPatternInteger i _ -> pp e i | ||
SyntaxPatternString i _ -> pp e i | ||
SyntaxPatternCons il _iv rl _rv -> pp e il <> pp e rl | ||
SyntaxPatternList ls -> foldMap (\(i, _) -> pp e i) ls | ||
SyntaxPatternAny -> text "_" | ||
SyntaxPatternEmpty -> text "()" | ||
in text "in case pattern" <> ppPattern p <> pp e k |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Clarify pattern printing.
SyntaxPatternIdentifier i _
SyntaxPatternInteger i _
SyntaxPatternString i _
SyntaxPatternCons ...
SyntaxPatternList ...
SyntaxPatternAny
SyntaxPatternEmpty
In printKont
, you display only the main pattern parts. If debugging intricate macros, you might want the variable names or capturing environment. Evaluate if more detail is necessary for diagnosing pattern failures.
|
||
execExpand :: ExpanderContext -> Expand a -> IO (Either ExpansionErr a) | ||
execExpand ctx act = runExceptT $ runReaderT (runExpand act) ctx | ||
|
||
execExpand ctx act = runDebug (runReaderT (runExpand act) ctx) initialContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review execExpand
for partial results.
execExpand ctx act = runDebug (runReaderT (runExpand act) ctx) initialContext
While returning Either ExpansionErr a
, confirm that partial expansions (e.g., incomplete tasks) are consistently handled or re-queued. If not, it might silently skip expansions.
src/Expander/Monad.hs
Outdated
Nothing -> debug $ InternalError "Missing expr after expansion" | ||
Just e' -> | ||
linkedScheme schPtr >>= | ||
\case | ||
Nothing -> throwError $ InternalError "Missing example scheme after expansion" | ||
Nothing -> debug $ InternalError "Missing example scheme after expansion" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the gathered information, I can now provide the final response:
Enhance error messages with source location for missing examples
The error messages should include the source location (loc
) that's already available in the Example
constructor. Update the error messages to:
Nothing -> debug $ InternalError $ "Missing expr after expansion at " <> show loc
Nothing -> debug $ InternalError $ "Missing example scheme after expansion at " <> show loc
The Example
constructor already carries location information (SrcLoc
) which includes file path, start, and end positions. This information should be used to help users identify which example is incomplete.
🔗 Analysis chain
Enhance example’s error.
Nothing -> debug $ InternalError "Missing expr after expansion"
Nothing -> debug $ InternalError "Missing example scheme after expansion"
Examples are user-facing. Provide the user with either a source location or snippet to identify which example is incomplete.
Let me gather more information about the error handling and example-related code to provide a thorough verification.
Let me search for more context about the Example constructor and location information.
Let me try one more search to find the location-related information.
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash
# Search for the context around the error handling
rg -B 5 -A 5 "Missing (expr|example scheme) after expansion" src/
# Look for example-related types and data structures
ast-grep --pattern 'data Example = $_'
# Find where examples are processed
rg -B 3 -A 3 "linkedScheme" src/
Length of output: 4268
Script:
#!/bin/bash
# Look for Example constructor definition and usage
ast-grep --pattern 'Example $_ $_ $_'
# Search for location-related types and usage
rg -B 2 -A 2 "type Loc = " src/
rg "data Loc = " src/
Length of output: 1431
Script:
#!/bin/bash
# Search for location usage in error messages and source locations
rg -B 2 -A 2 "stxSrcLoc|srcLoc|SrcLoc" src/
# Look for the Example constructor in data type definitions
rg -B 3 -A 3 "data (Decl|Tree|AST|Syntax)" src/
Length of output: 15343
klister.cabal
Outdated
@@ -42,6 +42,7 @@ common deps | |||
megaparsec >= 7.0.5 && < 9.7, | |||
mtl >= 2.2.2 && < 2.4, | |||
prettyprinter >= 1.2 && < 1.8, | |||
prettyprinter >= 1.2 && < 1.8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove redundant prettyprinter
dependency entry.
Line 45 duplicates the prettyprinter
constraint. Consider removing one entry to maintain clarity and avoid potential confusion in dependency management.
src/Expander.hs
Outdated
Nothing -> error $ show $ InternalError $ | ||
"No transformer yet created for " ++ shortShow ident ++ | ||
" (" ++ show transformerName ++ ") at phase " ++ shortShow p | ||
Just other -> throwError $ ValueNotMacro other | ||
-- debug $ InternalError $ | ||
-- "No transformer yet created for " ++ shortShow ident ++ | ||
-- " (" ++ show transformerName ++ ") at phase " ++ shortShow p | ||
Just other -> error "debug $ ValueNotMacro other" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace error calls with debug for transformer-related errors.
The error handling for transformer-related issues uses direct error
calls and has commented-out debug
statements.
Apply this diff to maintain consistency:
- Nothing -> error $ show $ InternalError $
- "No transformer yet created for " ++ shortShow ident ++
- " (" ++ show transformerName ++ ") at phase " ++ shortShow p
- -- debug $ InternalError $
- -- "No transformer yet created for " ++ shortShow ident ++
- -- " (" ++ show transformerName ++ ") at phase " ++ shortShow p
- Just other -> error "debug $ ValueNotMacro other"
+ Nothing -> debug $ InternalError $
+ "No transformer yet created for " ++ shortShow ident ++
+ " (" ++ show transformerName ++ ") at phase " ++ shortShow p
+ Just other -> debug $ ValueNotMacro other
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Nothing -> error $ show $ InternalError $ | |
"No transformer yet created for " ++ shortShow ident ++ | |
" (" ++ show transformerName ++ ") at phase " ++ shortShow p | |
Just other -> throwError $ ValueNotMacro other | |
-- debug $ InternalError $ | |
-- "No transformer yet created for " ++ shortShow ident ++ | |
-- " (" ++ show transformerName ++ ") at phase " ++ shortShow p | |
Just other -> error "debug $ ValueNotMacro other" | |
Nothing -> debug $ InternalError $ | |
"No transformer yet created for " ++ shortShow ident ++ | |
" (" ++ show transformerName ++ ") at phase " ++ shortShow p | |
Just other -> debug $ ValueNotMacro other |
Left err -> error (T.unpack (pretty err)) | ||
Right vioy -> pure vioy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace direct error call with debug for consistent error handling.
The error handling here is inconsistent with the rest of the changes in the file. Other locations use the new debug
functionality for error reporting.
Apply this diff to maintain consistency:
- Left err -> error (T.unpack (pretty err))
+ Left err -> debug $ MacroEvaluationError p err
Committable suggestion skipped: line range outside the PR's diff.
debug $ InternalError "All modules should be identifier-headed" | ||
DeclTreeDest {} -> | ||
throwError $ InternalError "All declarations should be identifier-headed" | ||
debug $ InternalError "All declarations should be identifier-headed" | ||
TypeDest {} -> | ||
throwError $ NotValidType stx | ||
debug $ NotValidType stx | ||
ExprDest t dest -> | ||
case syntaxE stx of | ||
List xs -> expandOneExpression t dest (addApp stx xs) | ||
Integer n -> expandOneExpression t dest (addIntegerLiteral stx n) | ||
String s -> expandOneExpression t dest (addStringLiteral stx s) | ||
Id _ -> error "Impossible happened - identifiers are identifier-headed!" | ||
PatternDest {} -> | ||
throwError $ InternalError "All patterns should be identifier-headed" | ||
debug $ InternalError "All patterns should be identifier-headed" | ||
TypePatternDest {} -> | ||
throwError $ InternalError "All type patterns should be identifier-headed" | ||
debug $ InternalError "All type patterns should be identifier-headed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace internal error calls with debug for consistent error handling.
Multiple internal errors are using direct error
calls instead of the new debug
functionality.
Apply this diff to maintain consistency:
- debug $ InternalError "All modules should be identifier-headed"
+ debug $ NotValidSyntax "All modules should be identifier-headed" stx
- debug $ InternalError "All declarations should be identifier-headed"
+ debug $ NotValidSyntax "All declarations should be identifier-headed" stx
- debug $ NotValidType stx
+ debug $ NotValidType stx
- Id _ -> error "Impossible happened - identifiers are identifier-headed!"
+ Id _ -> debug $ InternalError "Impossible happened - identifiers are identifier-headed!"
- debug $ InternalError "All patterns should be identifier-headed"
+ debug $ NotValidSyntax "All patterns should be identifier-headed" stx
- debug $ InternalError "All type patterns should be identifier-headed"
+ debug $ NotValidSyntax "All type patterns should be identifier-headed" stx
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
debug $ InternalError "All modules should be identifier-headed" | |
DeclTreeDest {} -> | |
throwError $ InternalError "All declarations should be identifier-headed" | |
debug $ InternalError "All declarations should be identifier-headed" | |
TypeDest {} -> | |
throwError $ NotValidType stx | |
debug $ NotValidType stx | |
ExprDest t dest -> | |
case syntaxE stx of | |
List xs -> expandOneExpression t dest (addApp stx xs) | |
Integer n -> expandOneExpression t dest (addIntegerLiteral stx n) | |
String s -> expandOneExpression t dest (addStringLiteral stx s) | |
Id _ -> error "Impossible happened - identifiers are identifier-headed!" | |
PatternDest {} -> | |
throwError $ InternalError "All patterns should be identifier-headed" | |
debug $ InternalError "All patterns should be identifier-headed" | |
TypePatternDest {} -> | |
throwError $ InternalError "All type patterns should be identifier-headed" | |
debug $ InternalError "All type patterns should be identifier-headed" | |
debug $ NotValidSyntax "All modules should be identifier-headed" stx | |
DeclTreeDest {} -> | |
debug $ NotValidSyntax "All declarations should be identifier-headed" stx | |
TypeDest {} -> | |
debug $ NotValidType stx | |
ExprDest t dest -> | |
case syntaxE stx of | |
List xs -> expandOneExpression t dest (addApp stx xs) | |
Integer n -> expandOneExpression t dest (addIntegerLiteral stx n) | |
String s -> expandOneExpression t dest (addStringLiteral stx s) | |
Id _ -> debug $ InternalError "Impossible happened - identifiers are identifier-headed!" | |
PatternDest {} -> | |
debug $ NotValidSyntax "All patterns should be identifier-headed" stx | |
TypePatternDest {} -> | |
debug $ NotValidSyntax "All type patterns should be identifier-headed" stx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation looks like a great application of the CEK-style evaluator!
Two things:
- The pretty-printer changes seem to be almost entirely regressions, grouping unrelated things and separating related things. They also make the diff harder to follow, because there's tons of noise in tests. Reverting most of the deletions of
group
should fix that, I think. What problem was it solving? - Why is there a list of
EState
s in a debug context? It seems to me that the debugger should get a single evaluator state.
error-in-arg.kl:5.24-5.27: | ||
bad | ||
stack trace: | ||
---- with function #<closure> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we provide more info here? Perhaps closures can contain the source position of their corresponding lambda?
@@ -0,0 +1,3 @@ | |||
#lang "prelude.kl" | |||
|
|||
(example (>>= (pure (error 'e)) (lambda (x) (pure x)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline!
(>>= (pure 'hello-go-boom) | ||
(lambda (x) | ||
(>>= (syntax-error x) | ||
-- TODO: why doesn't this work? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a strange error indeed!
|
||
printKont :: Env Var () -> Kont -> Doc VarInfo | ||
-- the basics | ||
printKont _ Halt = text "Halt" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In empty traces, this was a bit confusing. What about suppressing it, and then special-casing empty continuations at the outside?
<> pp e k | ||
|
||
-- pairs | ||
-- TODO: DYG: how to test the cons? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding unsafeCoerce
as a primitive for testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/Expander.hs (1)
1333-1347
: 🛠️ Refactor suggestionConsider using NotValidSyntax for better error reporting.
Replace
InternalError
withNotValidSyntax
for better error messages when handling invalid syntax.Apply this diff to improve error reporting:
- debug $ InternalError "All modules should be identifier-headed" + debug $ NotValidSyntax "All modules should be identifier-headed" stx - debug $ InternalError "All declarations should be identifier-headed" + debug $ NotValidSyntax "All declarations should be identifier-headed" stx - debug $ InternalError "All patterns should be identifier-headed" + debug $ NotValidSyntax "All patterns should be identifier-headed" stx - debug $ InternalError "All type patterns should be identifier-headed" + debug $ NotValidSyntax "All type patterns should be identifier-headed" stx
🧹 Nitpick comments (3)
src/Evaluator.hs (3)
11-25
: Consider enhancing the module documentation.While the module header is well-structured, it would benefit from additional details about:
- How the CEK machine state is converted to stack traces
- The relationship between debugging and stack traces
- Examples of stack trace output format
160-166
: Consider documenting performance implications.While the Note [InCasePattern] explains the debugging benefits, it would be helpful to document:
- Performance overhead of evaluating patterns in the interpreter vs. host runtime
- Any benchmarking results if available
- Scenarios where this overhead might be significant
629-667
: Consider refactoring pattern matching logic.The pattern matching implementation in
match
functions shows similar patterns that could be abstracted:
- Common pattern of extending environment and wrapping with
InCasePattern
- Similar error handling paths
Consider introducing a helper function:
matchWithPattern :: SyntaxPattern -> Core -> Value -> VEnv -> Kont -> EState -> (VEnv -> EState) -> EState matchWithPattern pat rhs scrutinee env k next success = case (pat, scrutinee) of (SyntaxPatternIdentifier n x, v@(ValueSyntax (Syntax (Stx _ _ (Id _))))) -> success $ extend n x v env _ -> next
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
klister.cabal
(1 hunks)src/Evaluator.hs
(10 hunks)src/Expander.hs
(26 hunks)src/Expander/Monad.hs
(13 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- klister.cabal
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: macOS-latest / ghc 9.6
- GitHub Check: ubuntu-latest / ghc 9.2.5
- GitHub Check: ubuntu-latest / ghc 9.4
- GitHub Check: ubuntu-latest / ghc 9.6
- GitHub Check: stack / ghc 9.2.8
🔇 Additional comments (18)
src/Evaluator.hs (1)
583-593
: Plan to remove stopgap error handling.The
constructErrorType
function is marked as a temporary solution. Consider:
- Creating a tracking issue for its removal
- Documenting the proper error handling approach that should replace it
- Adding tests to ensure consistent error handling behavior
Would you like me to help create a GitHub issue to track this technical debt?
src/Expander/Monad.hs (8)
177-177
: LGTM!The Debugger module import is correctly placed and aligns with the new error handling approach.
208-212
: LGTM! Monad transformation looks good.The change from
ExceptT
toDebug
monad is well-structured and maintains the required type class instances. TheMonadDebugger
instance is correctly derived.
215-215
: Verify handling of partial results in execExpand.While the change to use
runDebug
is correct, ensure that partial expansions are properly handled.Run this script to check for potential partial expansion scenarios:
#!/bin/bash # Search for expansion tasks that might be incomplete rg -B 2 -A 2 "forkExpanderTask|stillStuck" src/
599-599
: LGTM! Error handling is consistent.The error handling is properly updated to use
debug
and provides a clear error message.
Line range hint
610-623
: LGTM! Error handling is consistent.The error handling is properly updated to use
debug
with appropriate error messages for missing declarations and expressions.
632-632
: LGTM! Error handling is consistent.The error handling for missing expressions in macro definitions is properly updated to use
debug
.
657-661
: LGTM! Enhanced error messages with location information.The error handling for missing expressions and schemes in examples is properly updated to use
debug
and includes helpful source location information.
668-668
: LGTM! Error handling is consistent.The error handling for missing actions is properly updated to use
debug
.src/Expander.hs (9)
153-156
: LGTM! Error handling is consistent.The error handling for file existence and reader errors is properly updated to use
debug
.
199-199
: LGTM! Error handling is consistent.The error handling for non-exported identifiers is properly updated to use
debug
.
851-851
: LGTM! Error handling is consistent.The error handling for no progress in tasks is properly updated to use
debug
.
Line range hint
867-870
: LGTM! Error handling is consistent.The error handling for macro evaluation errors is properly updated to use
debug
.
915-919
: LGTM! Error handling is consistent.The error handling for type case evaluation errors is properly updated to use
debug
.
1324-1329
: LGTM! Error handling is consistent.The error handling for macro expansion errors is properly updated to use
debug
with appropriate error messages for various failure cases.
1411-1417
: LGTM! Error handling is consistent.The error handling for macro evaluation errors is properly updated to use
debug
with appropriate error messages.
1424-1432
: LGTM! Error handling is consistent.The error handling for identifier comparison is properly updated to use
debug
with appropriate error messages and exception handling.
1440-1440
: LGTM! Error handling is consistent.The error handling for invalid syntax objects is properly updated to use
debug
.
projectError :: EState -> EvalError | ||
projectError (Er err _env _kont) = err | ||
projectError _ = error "projectError not used on an error!" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve type safety of projectError.
The projectError
function could panic if called with non-error states. Consider:
- Using Haskell's type system to prevent invalid usage
- Returning
Maybe EvalError
instead of using error
projectError :: EState -> Maybe EvalError
projectError (Er err _env _kont) = Just err
projectError _ = Nothing
4de0c16
to
cc73f7f
Compare
Todos:
>>=
tail andpair
@gelisam @david-christiansen, sorry for the size of this one. I wanted to open this to get some eyes on it.
How can I test the
InMacroBindTL
andpair
cases? No matter what kind of klister I wrote, I could not get those to show up.Also, you'll notice that I chose to add a hardline to separate the error message from the error context. We should decide on a format in the next meeting
Summary by CodeRabbit
Release Notes
New Features
Improvements
Internal Changes
Development Environment
cabal-install
to development tools.