Skip to content

Function Keyword vs Return Type: Why Modern Languages Use fn/func

Purpose

This post explains why modern programming languages like Go, Rust, and Kotlin use dedicated fn/func keywords instead of the C-style return-type-first syntax.

When I started learning these languages, I noticed they all put the function name before the return type. This seemed different from C and C++. I wanted to understand why.

The C-Style Approach

In C and C++, you write functions like this:

example.c
int calculate(int x) {
return x * 2;
}

The return type comes first. This is how I learned programming. But there’s a problem: you don’t know if int x is a variable or a function until you see what comes next.

int x = 5; // Variable
int x() { ... } // Function
int x(); // Function declaration

The parser and your brain have to look ahead to figure it out.

The Modern Approach

Modern languages use a keyword first:

example.rs
fn calculate(x: i32) -> i32 {
x * 2
}
example.go
func calculate(x int) int {
return x * 2
}

The fn or func keyword tells you immediately: this is a function. No ambiguity.

Why This Matters

Less Mental Load

When I read code, I scan it quickly. With keyword-first syntax, I can see fn or func and know it’s a function without parsing the whole line.

With return-type-first, I have to check:

  • Is this a variable declaration?
  • Is this a function definition?
  • Is this a function declaration?

This takes more cognitive effort.

Easier Scanning

I scan for function names more often than return types. When I look at a file, I want to see what functions are available.

Return-Type-First Keyword-First
int calculate() fn calculate() -> int
std::string getName() fn getName() -> String
std::map<K,V> getData<K,V>() fn getData<K,V>() -> Map<K,V>

With keyword-first, all function names start at the same column. They align visually. This makes scanning easier.

Better with Generics

Modern languages use generics a lot. Return types can get complex.

// This would be hard to read with return-type-first
Result<HashMap<String, Vec<Arc<Mutex<Box<dyn Any>>>>>, Box<dyn Error>>
parse(input: &str)
// Actual Rust syntax is clearer
fn parse(input: &str) -> Result<HashMap<String, Vec<Arc<Mutex<Box<dyn Any>>>>>, Box<dyn Error>>

The function name parse comes first. I can see what it does before wading through the complex return type.

Parser Efficiency

I read about how language parsers work. The fn keyword is the first token. The parser knows it’s a function immediately.

This means:

  • Faster syntax highlighting
  • Quicker code navigation
  • Better IDE autocomplete

Language Comparison

Let me show how different languages handle this:

Go:

go_example.go
func process(data []byte) (result []byte, err error) {
// Implementation
}

Rust:

rust_example.rs
fn parse_with_lifetime<'a>(input: &'a str) -> &'a str {
// Implementation
}

Kotlin:

kotlin_example.kt
fun processData(input: String): Result<String> {
// Implementation
}

C++ (for comparison):

cpp_example.cpp
std::vector<std::pair<std::string, int>>
processData(const std::string& input) {
// Implementation
}

Notice how the C++ example has the function name processData buried in the middle. In the modern languages, it’s right after the keyword.

What About Trade-offs?

I tried to think about when return-type-first might be better.

When Return-Type-First Works

  • Simple functions with short return types
  • When you care more about what a function returns than what it’s named
  • Type inference scenarios like C++ auto

When Keyword-First Shines

  • Generic programming with complex types
  • Large codebases where you need to scan quickly
  • Code with lots of function declarations
  • When function names matter more than return types

My Experience

When I started learning Rust after years of C++, I found the fn keyword strange at first. It felt like extra typing.

But after using it for a while, I noticed:

  • I could scan code faster
  • I understood new codebases quicker
  • Function signatures felt more natural

Now when I go back to C++, I find myself searching for function names in the middle of lines.

Summary

In this post, I explained why modern languages use fn/func keywords instead of return-type-first syntax.

The key point is that keyword-first syntax reduces cognitive load and makes code easier to scan. You can identify functions immediately without parsing the whole line. This matters more as code gets complex with generics and large codebases.

Modern language designers chose readability and tooling support over minimal syntax. The extra keyword token is a small price to pay for clearer code.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments