# Debugging

Part of what sets Medley apart is a collection of dedicated functions and features to help us debug our programs.

#### **FIX and ED**

`FIX line-number` :

`FIX` lets us edit whatever we typed at a specific line number. It's useful when we want to make an immediate change.

<figure><img src="/files/0kfcbwdFksTTz8pScG5o" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Remember, we can refer to line numbers from any Exec. You might find it helpful to work with multiple smaller Execs, each focusing on a unique function of the larger program.
{% endhint %}

Back in the SEdit chapter, we learned about editing the definition of a function with `(DF function-name)`, which Medley internally translates to `(ED 'NAME '(FUNCTIONS FNS :DONTWAIT))`. You don't need to use this expanded form, but it's good to know what goes on in the background.&#x20;

&#x20;`(ED 'function-name)`

While `DF` is for editing functions only, `ED` is the default editor function we can use to edit any File Manager object, including function definitions, variable values, property lists, or file package commands through SEdit.

{% hint style="info" %}
The `:DONTWAIT` statement in DF’s call to ED lets SEdit return immediately, so the Exec doesn’t stall after starting an edit. This means you can continue working in the Exec while making edits in SEdit and changes take effect as you make them, without waiting for a completion command.&#x20;

Try both DF and ED to edit a function. Does one of them let you switch to the Exec freely? Which one restricts you to SEdit?
{% endhint %}

***

#### **INSPECT**

At times, you will define variables containing values more complex than an atom. As our programs grow larger, we might want to take a quick look at the contents of these variables in an organized, tabular format without opening an editor like SEdit:

<figure><img src="/files/k7eo8TUJspLAiHdYBoKg" alt=""><figcaption></figcaption></figure>

`INSPECT`allows us to do exactly that:

<figure><img src="/files/Ku11aJsK7WKei30H46Ll" alt=""><figcaption></figcaption></figure>

Select Inspect from the menu, and a window appears with two columns. The first column displays the numbered positions of the list items, and the second column displays the item in that position.

<figure><img src="/files/1VxgujxdrFLi44MKUYK0" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Notice how we use a quote (') before the variable name when we need to edit the definition of the variable. The system does not need to evaluate or understand the contents. It only needs to display the contents for us to make changes. Quote (') tells Lisp not to evaluate or "run" what follows.\
\
But when it comes to Inspect, we do want the system to understand the contents of the list so it can organize and display it neatly for us to review. No quotes for that operation!
{% endhint %}

***

#### BREAK

`BREAK` sets a breakpoint, letting you halt a function midway and inspect what might be going wrong in a dedicated Break Window. We can break and unbreak entire functions. This is handy when your function is huge, complex, and expensive to compute. We can also insert conditional breakpoints inside a function that breaks the function if certain criteria are met. This is useful when you want to ask questions about the flow of data through your program. Or when you want your program to stop its operation if (as opposed to printing the state and continuing).

{% hint style="info" %}
If you're stuck in an infinite loop or just want to break out of the current running function, use **Ctrl + B.**
{% endhint %}

In a COND, use `(ERROR "Something meaningful to print about the break")` to trigger a break at a when you detect an error condition.

Let's define a function that prints out the factorial of any given number.

<figure><img src="/files/JQla8HdBOBCu5hRV37gH" alt=""><figcaption></figcaption></figure>

Factorials can be quite large. Suppose we want to limit the program so that only factorials of numbers no greater than 10 are printed. Pull up SEdit to edit the function `factorial`. Add another condition to the COND block:&#x20;

`((GREATERP X 10) (ERROR "This number is too large. X should be less than 11."))`

This tells Medley to break the function if X is greater than 10.

<figure><img src="/files/VMKbxh6Qd59WGXOzvLXk" alt=""><figcaption></figcaption></figure>

Once the new function is compiled, try a few different values to test if it's working as intended.&#x20;

For `(factorial 11)`, or any number larger than 10, you should see the break window appear with your message:

<figure><img src="/files/tpIVtVbxUhb3lx9YtaTH" alt=""><figcaption></figcaption></figure>

***

#### TRACE

When your program is not acting as intended, the final output might not necessarily reveal what you need to fix. Being able to look at the internal calculations your functions are making and what output they generate at every step is a useful feature, and TRACE lets us do exactly that.&#x20;

Let's trace our factorial function.

<figure><img src="/files/WqvFMAfF2vV6loycVrjT" alt=""><figcaption></figcaption></figure>

After we've traced a function with `TRACE function-name`, executing the function will open a Trace-Output window:

<figure><img src="/files/tPj1UocTfGmLMfDzjL8s" alt=""><figcaption></figcaption></figure>

To stop tracing a function use `UNTRACE`:

<figure><img src="/files/yfDTaVgjMaevfxKU8Wqk" alt=""><figcaption></figcaption></figure>

***

#### ADVISE

As our programs grow more complex, we might not want to change the original code when we need to make a small, temporary change. `ADVISE` is a Medley feature to modify the behavior of a function by wrapping code "around" that function without having to edit it. It's also useful when you're working with someone else's code and want to preserve the integrity of their code.

The `ADVISE` function takes four arguments:\
`(ADVISE function-name WHEN WHERE WHAT)`

`WHEN` specifies when in the function call should the advised code be executed. Before the function, after the function, or should it replace the function's body entirely by executing around it? `WHEN` has three valid parameters: `BEFORE`, `AFTER`, `AROUND`

`WHERE` specifies where in a list of advice the current advise should be inserted. `WHERE` has two valid parameters: `FIRST` or `TOP` and `LAST` or `BOTTOM` or `END`. We can use `NIL` for `WHERE` unless we have multiple advises. If `WHEN` is `AROUND`, `WHERE` is considered NIL.

`WHAT` is the advised code to run.

Let's advise our factorial function to check if X is a string or a number:

<figure><img src="/files/kQdX2nyMLJMZJfmKraTo" alt=""><figcaption></figcaption></figure>

Now, when we execute `factorial`, we see:

<figure><img src="/files/2floS0kmvQpc0wudc4Es" alt=""><figcaption></figcaption></figure>

We can remove advice from a function using `UNADVISE`:

<figure><img src="/files/0SuZbu3GP7xrSw1Pw8uP" alt=""><figcaption></figcaption></figure>

Try adding two ADVISEs to a new function. One should appear before and one after the function is executed.

<figure><img src="/files/FZ8xcDGRtCAkI2PmnnAG" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
!VALUE can be used to access the final value of the function. \
PROGN executes what follows sequentially. We'll learn more about it in the next chapter.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://primer.interlisp.org/debugging.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
