Idea: Enum/Struct definition within function header


#1

Hi there,

I had a little idea a while ago and I’m curious what you think of it. Sometimes I want to have a enum function parameter, but I just need to use it inside that function. So its a bit annoying to write my enum definition somewhere else (possibly right above my function?). Also it’s annoying when reading code, seeing a new type in a function header and searching for it’s definition although it might just be enum { North, South }.

New Syntax

I thought about something like

fn get_coord(dir: Direction) where Direction: enum { North, South } {
    ...
}

// call it
get_coord(Direction::North);

The where block is just perfect for small inline definitions. This could be useful for struct definitions, too, although you could just add more parameters instead of one struct parameter. A more complex example could be:

fn get_coord<T: Add + Mul>(old: Coord, dir: Direction)
    where Coord: struct { x: T, y: T },
          Direction: enum { North, West, South, East } 
{ ... }

// call it
get_coord(Coord { x: 3u32, y: 27 }, Direction::South);

The scope of the defined type would be the same as the scope of the function.

Advantages

  • Small type definitions are right where you need them
  • better to read & faster to write
  • Stuff that belongs together semantically is together in code too

Disadvantages

  • Language syntax becomes more complex
  • You might find yourself first writing this kind of inline definition and later changing it to a “normal” definition, because the type has become more complex. This might be annoying.
  • We’d need to say something about it in the style guide to prevent misuse (e.g. how many enum-variants at max, etc.)

Alternatives

Do nothing.


So yeah, what do you think? Really curious about that :blush:

Lukas


#2

You get the same advantages by just putting the definition next to the function, with none of the disadvantages.


#3

See also: https://github.com/rust-lang/rfcs/issues/294


#4

Feels kinda out-of-place. It doesn’t seem to add anything to the language and it adds significant complexity. I’ve personally never had a case where this would useful. Most of the time the types, even if they’re simple, will be used multiple times. Even in your example, I’d find it surprising if Direction was used only in a single function/method.


#5

Thanks for your feedback!

You get the same advantages by just putting the definition next to the function, with none of the disadvantages.

When a codebase grows over time it may happen that anyone puts another definition between your type and your function. Putting it above doesn’t say “it belongs to that function” as clearly.

Most of the time the types, even if they’re simple, will be used multiple times.

I guess thats pretty much always the case, yes.

So I think it’s not bad, but I agree it adds to much complexity. Just wanted to mention it here in case anyone is interested in it in the future.