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

debugging guide #1505

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

harshkpatel
Copy link
Contributor

@harshkpatel harshkpatel commented Jan 31, 2025

Proposed Changes

(Describe your changes here. Also describe the motivation for your changes: what problem do they solve, or how do they improve the application or codebase? If this pull request fixes an open issue, use a keyword to link this pull request to the issue.)

This PR is added to improve the developer experience and provide them with a proper introduction/guide on debugging in haskell. From my own personal experience, this would have been useful to learn early on as the tools definitely have their use cases and are a lot better than simply using the print monad.

...

Screenshots of your changes (if applicable)

Type of Change

(Write an X or a brief description next to the type or types that best describe your changes.)

Type Applies?
🚨 Breaking change (fix or feature that would cause existing functionality to change)
New feature (non-breaking change that adds functionality)
🐛 Bug fix (non-breaking change that fixes an issue)
🎨 User interface change (change to user interface; provide screenshots)
♻️ Refactoring (internal change to codebase, without changing functionality)
🚦 Test update (change that only adds or modifies tests)
📦 Dependency update (change that updates a dependency)
🔧 Internal (change that only affects developers or continuous integration) x

Checklist

(Complete each of the following items for your pull request. Indicate that you have completed an item by changing the [ ] into a [x] in the raw text, or by clicking on the checkbox in the rendered description on GitHub.)

Before opening your pull request:

  • I have performed a self-review of my changes.
    • Check that all changed files included in this pull request are intentional changes.
    • Check that all changes are relevant to the purpose of this pull request, as described above.
  • I have added tests for my changes, if applicable.
    • This is required for all bug fixes and new features.
  • I have updated the project documentation, if applicable.
    • This is required for new features.
  • If this is my first contribution, I have added myself to the list of contributors.
  • I have updated the project Changelog (this is required for all changes).

After opening your pull request:

  • I have verified that the CircleCI checks have passed.
  • I have requested a review from a project maintainer.

Questions and Comments

Wish I made this eariler, this probably would have made me a bit more efficient at working through problems, but I am glad I got to learn about these tools indepth!

@coveralls
Copy link

coveralls commented Jan 31, 2025

Pull Request Test Coverage Report for Build 2179d9f8-c384-4e98-8acb-8090ad328cb7

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 45.914%

Totals Coverage Status
Change from base Build 6c8565e1-084f-40f1-909b-165579817bd9: 0.0%
Covered Lines: 533
Relevant Lines: 1137

💛 - Coveralls

@harshkpatel harshkpatel changed the title inital_draft debugging guide Feb 5, 2025
@harshkpatel harshkpatel marked this pull request as ready for review February 5, 2025 01:35

## Introduction

There is a general purpose debugging guide available [here](https://wiki.haskell.org/Debugging), but it
Copy link
Contributor

Choose a reason for hiding this comment

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

In general, do not worry about line length. Instead, write each sentence on a single line. This will make diffs more useful when we make future updates.


There is a general purpose debugging guide available [here](https://wiki.haskell.org/Debugging), but it
is outdated and lacks information on how to navigate a modern debugger like gdb. This guide will look two main
cases for debugging a program in Haskell. The first being printing in the code using
Copy link
Contributor

Choose a reason for hiding this comment

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

"cases" -> "techniques"


## Debug.Trace

This library is a quick and effective way to print values of objects in your Haskell Program. Please refer to the
Copy link
Contributor

Choose a reason for hiding this comment

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

This section should describe two functions: trace and traceM. Show the type signatures and explain where to use each one. You don't need to discuss other functions.

This library is a quick and effective way to print values of objects in your Haskell Program. Please refer to the
documentation about which specific functions to use for your use case. To be more specific, a different function will
be called if you want to print a monad type object, a primitive type object or an algebraic datatype object. First you
need to `import Debug.Trace` at the top of your file. The following example below shows usage for a monadic type, since
Copy link
Contributor

Choose a reason for hiding this comment

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

In general, do not emphasize the use of monads. Instead, provide two examples: one of trace and one of traceM. You can explain the difference but avoid phrases like "Courseography is packed with Monads".


First we add `traceM` after the monad we want to view:

![Image](images/debugTrace.png)
Copy link
Contributor

Choose a reason for hiding this comment

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

Code should be displayed as code blocks, not screenshots. It's a good idea to use specific examples drawn from the codebase, and when doing so you should provide a reference and link to the specific file where the example is drawn from.


Stepping through the program can be done using `:step`. This will step through the program until the next breakpoint.
There are two variants `:steplocal` and `:stepmodule`, where the former limits the breakpoints that are enabled to the
scope of the current function and the latter restricts the scope of the breakpoints to the current module. **To reiterate
Copy link
Contributor

Choose a reason for hiding this comment

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

Do not reiterate warnings. Say the warning once at the end of this section, in a separate paragraph.

until the result of the entire program is printed, but if main is called again in the same session, it will be evaluated
and the stepper environment will not be available**.

Functions can also be called. Type the function and its input parameters directly into the debugger: `function inputs`.
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to provide an example, this is standard function call syntax. You just need to say that breakpoints can apply to functions called in ghci directly.


![Image](images/debugTraceOutput.png)

## GHCi Debugger
Copy link
Contributor

Choose a reason for hiding this comment

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

Please read through https://downloads.haskell.org/ghc/latest/docs/users_guide/ghci.html#the-ghci-debugger to gain a deeper understanding of this tool.

Also, you should link to this documentation as an additional resource (somewhere in the guide).

and the stepper environment will not be available**.

Functions can also be called. Type the function and its input parameters directly into the debugger: `function inputs`.
The downside about doing this is that information is lost with respect to specific input values if this is done during
Copy link
Contributor

Choose a reason for hiding this comment

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

Investigate further this behaviour before claiming a limitation (see the link I provided to the ghci documentation). You might need to use :force instead of :print.

debugging with breakpoints. To be more specific, the debugger will tell you the algebraic types of the variables,
but it won't tell you what the actual values are.

You can also see an entire trace of debugging a function with `:trace`. Set the breakpoint at the function's base case/
Copy link
Contributor

Choose a reason for hiding this comment

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

This paragraph is more advanced, and I don't recommend including this here. Just stick to the basics and make sure they are explained as clearly as possible.

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.

3 participants