Despairing over writing a function

I’m thinking of writing a novel. To be able to easily track who appears where, I was thinking of using a function per character. I want the function without argument to just return the name. An argument would either be an alternate name form, or empty for paragraphs where a human would know from context who’s speaking. Something like

#Liz said: "Oh, wow!"

#Liz[Elizabeth] said: "Oh, wow!"

#Liz[She] said: "Oh, wow!"

#Liz[] "Oh, wow!"

As far as I understand it, this argument can not have a default, since then it would have to be named. But, if I have a positional or variadic argument, it seems to default to the function name (value is Liz in a different font.) None of these seem to work

#let Liz(alt) = if alt == Liz { [Liz] } else { alt }
#let Liz(alt: [Liz]) = alt
#let Liz(..alt) = if alt.len() == 0 { [Liz] } else { alt.at(0) }

I’ve read the doc up and down, but it is fairly vague on details. How can I implement such a simple requirement?

There are a couple of issues with your definition of Liz:

  • Using a function without arguments doesn’t invoke it but inserts the function name.
  • alt is an arguments object; you may want to call .pos() to get at the positional arguments.
  • An empty positional argument is still an argument, so #Liz[] does have one argument, albeit an empty one.

Here is a modification of your example that kind of works:

#let Liz(..alt) = {
  let nomen = alt.pos().at(0)
  if nomen == [] {
    [Liz]
  }
  else {
    nomen
  }
}
#Liz[] comes.
#Liz[She] goes.

produces “Liz comes. She goes.”

As a minor note, with the approach you took, ..alt can be replaced with nomen since the argument is not always given again. The sample showing how to use arguments is still useful though!