What is the simplest way to define multiple similar functions?

hey! i’m writing a small math library which includes this snippet:

#let theorem_impl(type, caption, body) = {
  align(
    center,
    figure(
      caption: figure.caption(
        position: top,
        caption,
      ),
      kind: lower(type),
      supplement: type,
      box(
        fill: rgb("#eee"),
        stroke: 1pt + rgb("000"),
        inset: 5pt,
        body,
      ),
    ),
  )
}

#let theorem(caption: [], body) = theorem_impl(
  "Theorem",
  caption,
  body,
)

#let proposition(caption: [], body) = theorem_impl(
  "Proposition",
  caption,
  body,
)

#let lemma(caption: [], body) = theorem_impl(
  "Lemma",
  caption,
  body,
)

i was curious if there’s a manner by which to label the three derivative functions dynamically via a loop, as opposed to manually defining each of them, as the naive solution:

#for theorem-type in ([Theorem], [Proposition], [Lemma]) {
  let theorem-type(caption: [], body) = theorem_impl(
    type,
    caption,
    body,
  )
}

did not seem to work. thanks!

Defining functions in a loop won’t work, as they would then only be accessible from inside the loop. However, you can simplify your code a bit by using the with function to pre-apply some arguments:

#let theorem_impl(type, caption: [], body) = {
  ...
}

#let theorem = theorem_impl.with("Theorem")
#let proposition = theorem_impl.with("Proposition")
#let lemma = theorem_impl.with("Lemma")

The with function here gives you a new function where the type parameter is already set to the passed value. Note that I added a default value for the caption parameter, as the new functions will share the same parameter structure as the original implementation.

For completeness, I want to point out that there already exist some packages for theorems, such as ctheorems, lemmify, and great-theorems.


On an unrelated note, please try to put any questions in the Questions category. If you can move this topic yourself, don’t hesitate to do so. If not, don’t worry, as a moderator will take care of it.

1 Like

thanks! ill take a look at the existing packages as well, they look great, and i appreciate the explanation. ive moved the post to questions, too.