Feature idea: tracking function calls

I want to be able to tell if a function calls, or might call a certain other function without having to dig through the code. This probably has multiple solutions using the type system, but a more lightweight solution could be to just use tooling to get this information, without actually statically enforcing it.
(Eg. a type system solution might be to make my trackedFun return a TrackedFunResult a which we would only allow to be unpacked at the top level, but this obviously doesn’t scale well, and I might not need this mechanic in place at all times, just when I’m trying to understand the code)

My proposition:

  • Allow functions to be marked.
  • Allow functions to be queried if they call (or if they might call) marked functions.

Example:

{-# MARKED #-}
markedFun : Int -> Int
markedFun x = x + 1

{-# MARKED #-}
otherMarkedFun : Int -> Int
otherMarkedFun x = x - 1

doSomeStuff :: Int -> Update Int
doSomeStuff x = do
  stuff $ markedFun x

-- codelens: f always calls "markedFun", potentially calls "otherMarkedFun"
f : Int -> Update ()
f x = do
  y <- doSomeStuff x
  when (y > 0) $
    stuff $ otherMarkedFun y

I didn’t want to dig into the code before I get some feedback if something like this would be accepted into Daml, but I feel like this would be relatively simple to implement. I would be willing to spend time on this.

1 Like

Hi Krisztian,

There isn’t a way to do this currently in Daml. You might want to look into the Daml Visual tool, which creates a graph of template choices to help people visualize a DAR. Note that it only keeps track of choices, not functions. This tool is not actively developed.

A more hands-on approach that may be helpful is adding trace and debug calls in your code:

markedFun : Int -> Int
markedFun x = trace "markedFun called" (x + 1)

otherMarkedFun : Int -> Int
otherMarkedFun x = trace "otherMarkedFun called" (x - 1)

f : Int -> Update ()
f x = do
  debug "f started"
  y <- doSomeStuff x
  when (y > 0) $
    stuff $ otherMarkedFun y
  debug "f ended"

This only tells you the runtime behavior, but maybe that’s good enough to help understand some new code. Like the docs say, you will have to run sandbox with --log-level=debug to see the output.

As for implementing this as a new feature, I think it would be fine as part of Daml Visual. Ideally you would specify that you want to visualize functions on the command-line, maybe by passing a list of functions that you are interested in as command-line arguments. I would not try to modify the actual daml parser or daml compiler to add this feature.

Another way of tackling this would be via IDE tooling. E.g., “find references” is a pretty common feature in other IDEs. We don’t support that at the moment unfortunately but I think adding this makes more sense than adding special markers.

For dynamic information, a step-through debugger with breakpoints (also not yet implemented) could work well.