Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function Generics Seems Redundant #2842

Closed
Havvy opened this issue Jul 8, 2012 · 6 comments
Closed

Function Generics Seems Redundant #2842

Havvy opened this issue Jul 8, 2012 · 6 comments

Comments

@Havvy
Copy link
Contributor

Havvy commented Jul 8, 2012

Given this function signature:

fn bimap<K, V> (map: hashmap<K, V>) -> bimap<K, V>

The addition of <K, V> on the function name (bimap) seems redundant, and is an element of surprise to new users of the language (if I count as a new user.)

@catamorphism
Copy link
Contributor

What part of it seems redundant?

@bstrie
Copy link
Contributor

bstrie commented Jul 8, 2012

@catamorphism The markdown was obscuring his argument, take a look once more. :)

@catamorphism
Copy link
Contributor

@bstrie I saw it; the question still stands. bimap occurs twice: as a type and a value. So I'm not sure which occurrence @Havvy was referring to.

@Havvy
Copy link
Contributor Author

Havvy commented Jul 8, 2012

The function name. Sorry.

@catamorphism
Copy link
Contributor

It's true that it would be pretty simple to infer the bindings for type parameters in this case. But if you wrote a function with bounded type parameters (that is, "T must have trait foo"), it wouldn't be as straightforward (the typechecker would need to look at the whole function body, not just the signature). To keep type inference simple, we don't want to have to scrutinize the entire body to know the bounds for the type parameters. That is, if your function was:

fn bimap<K: Ord, V> (map: hashmap<K, V>) -> bimap<K, V>

then the type signature by itself doesn't give you enough information to infer that K must have trait Ord.

For consistency, we require type parameter bindings for all type parameters, not just bounded ones.

@pcwalton
Copy link
Contributor

pcwalton commented Jul 8, 2012

In Rust, the rule is that ∀ is always explicit. In type-theoretic notation, the type of bimap is

∀K,V.hashmap<K,V> → bimap<K,V>

Consider that if the ∀ were in a different location, it wouldn't typecheck. The type above is distinct from this type:

(∀K,V.hashmap<K,V>) → (∀K,V.bimap<K,V>)

So I think Rust's rules help clarity. And, as Tim mentioned, we need a place to put trait bounds.

@pcwalton pcwalton closed this as completed Jul 8, 2012
RalfJung pushed a commit to RalfJung/rust that referenced this issue Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants