Best practices for specifying return type

Is there a “best practice” for defining the return type of for example a file reading function?

There used to be the option to explicitly define a parametric type of a function, something like read_file{Float64}(....) upon which I would then use the specified type as the type of the returned value(s).

From what I understand this is now only possible related to defining types? This made it so now I changed all these kind of functions to `read_file(filename, T=Float32) so that users can explicitly change the return type if they want. This feels clunky though, is there a better way?

The behavior of a function should depend on its arguments.

If the type of the returned value can’t be determined from a set of arguments (eg filename above), extra ones should be added to specify it explicitly; perhaps providing a reasonable default if that makes sense. See, eg, rand, ones, zeros; it is quite standard.

I see, so it seems that the way julia Base does it is by letting you optionally specifying the type first. I’ll also adopt this way of working then. Thanks for the reply!

Optional and keyword arguments are also fine. Also other positions than the first argument are common, see the methods of read, eg read(stream::IO, T, dims).

Okay, are you aware of any philosophy behind the choice to either put it first or somewhere else in the argument list? If there isn’t any, would it be useful to adopt some kind of unified way of doing things, similar to the ! in the function name when it changes arguments?

I think this is one of those hard questions of API design. My “philosophy” is not to worry to much about it ex ante, and be ready to reshuffle things when refactoring, if some consistent pattern suggests itself.

3 Likes