TrixiParticles.jl icon indicating copy to clipboard operation
TrixiParticles.jl copied to clipboard

Use mandatory keyword arguments instead of positional arguments?

Open efaulhaber opened this issue 2 years ago • 6 comments

In most example files, we have

viscosity = ArtificialViscosityMonaghan(0.02, 0.0)

If you're not familiar with the API, you'd have to check the Julia help to see that the first positional argument is alpha and the second is beta. In many places, we do this instead:

alpha = 0.02
viscosity = ArtificialViscosityMonaghan(alpha, 0.0)

This makes it clear that the first positional argument is alpha, and it allows us to overwrite this with trixi_include. However, doing this everywhere will create quite a bit of extra code.

We could also use mandatory keyword arguments, so that the line above becomes

viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0)

Here, we can natively use trixi_include without further modification.

The Trixi.jl API is slowly moving away from positional arguments for exactly this reason. But they often allow both options: https://github.com/trixi-framework/Trixi.jl/blob/276dc3ca22a4c72b81aa6659e57ff1382dd1ae0c/src/solvers/dgsem/dgsem.jl#L54-L69

Do we want to

  1. keep things like they are?
  2. have keyword arguments instead of positional arguments?
  3. allow both?

I don't like option 3, as it makes the API more complicating by adding more options to do the same thing.

efaulhaber avatar Nov 07 '23 10:11 efaulhaber

Of course, when writing new code instead of modifying an existing example file, one has to first figure out the names for the keyword arguments (e.g., is it r or radius?), but with positional arguments, one has to figure out the order, so that doesn't make any difference to me.

efaulhaber avatar Nov 07 '23 10:11 efaulhaber

In some cases, it makes sense to have kwargs. But having a hard rule to only allow kwargs in the API might be too restrictive, and in some cases, it makes the example files even more unreadable, IMO. I can live with 1. and add kwargs where it makes sense (like so in ArtificialViscosityMonaghan). Also, we then have to think about default values, right?

LasNikas avatar Nov 07 '23 10:11 LasNikas

I'm not talking about a hard rule or only using keyword arguments. Just for things like viscosity, state equations, setups maybe.

efaulhaber avatar Nov 07 '23 10:11 efaulhaber

Also, we then have to think about default values, right?

No, you can just have kwargs without default values - it just makes them mandatory kwargs then. Usually it is much harder to use this in a wrong way than using only positional args. And if you insist on having the values defined elsewhere, you can also just use kwarg expansion, e.g.,

# Define kwarg-based ctor
function ArtificialViscosityMonaghan(alpha, beta) # (1)
    ...
end
ArtificialViscosityMonaghan(; alpha, beta) = ArtificialViscosityMonaghan(alpha, beta) # (2)

# Get values
alpha = get_alpha()
beta = get_beta()

# Construct in any of the following ways
ArtificialViscosityMonaghan(alpha, beta) # calls (1)
ArtificialViscosityMonaghan(alpha=alpha, beta=beta) # calls (2)
ArtificialViscosityMonaghan(; alpha, beta) # also calls (2)

# Compare wrong order
ArtificialViscosityMonaghan(beta, alpha)   # calls (1) but with wrong order
ArtificialViscosityMonaghan(; beta, alpha) # calls (2) but all arguments are still correctly assigned!

sloede avatar Nov 07 '23 10:11 sloede

Ah , I see. Then it makes sense for viscosity, eos and setups

LasNikas avatar Nov 07 '23 10:11 LasNikas

We can start with #279.

efaulhaber avatar Nov 07 '23 10:11 efaulhaber