carbon-lang icon indicating copy to clipboard operation
carbon-lang copied to clipboard

Proposal for Syntaxes - Function return type and Generics

Open dsriniv opened this issue 2 years ago • 9 comments

Firstly I want to say the presentation at CPPNorth was outstanding. Great work guys.

I had a couple of suggestions - I am not sure how open you are to changing the syntax styling.

  1. The arrow for runType seems very PHP. I like the fact carbon derives inspiration from Typescript and Kotlin.

Current

fn functionName() -> SomeReturnType {
return SomeReturnType();
}

Proposed

// With colon just like typescript
fn functionName() : SomeReturnType {
return  SomeReturnType();
}

// or when single line.
fn functionName() = SomeReturnType();
  1. Square bracket for generics is not intuitive. Instead, could we use angle brackets (<T: SomeType>)? Square brackets are more intuitive for Arrays...

dsriniv avatar Jul 25 '22 12:07 dsriniv

The : return type syntax is a popular request, and has the majority of upvotes in https://github.com/carbon-language/carbon-lang/discussions/1520#discussioncomment-3200131. Given also that two existing successful successor languages (Kotlin and TypeScript) use it, there is considerable precedent.

The argument for -> is that function types look weird with the colon syntax: var func: (i32): i32, and so the arrow should be used in both places for consistency with var func: (i32) -> i32. But this is optimizing for the rarer case. Return type annotations and variable/parameter type annotations are way more common than function types, so it would make sense to optimize for a consistent syntax for them.

emlai avatar Jul 25 '22 12:07 emlai

@emlai - Thank you for the explanation. I upvoted the comment as well.

dsriniv avatar Jul 25 '22 13:07 dsriniv

We've been trying to avoid angle brackets because they create very serious parsing problems. For example, a correct C++ parser has to implement substantial parts of C++'s name lookup and type checking rules, because in order to parse x<y, it has to figure out whether x is a template, in order to decide whether the < is a less-than operator or an open angle bracket.

geoffromer avatar Jul 26 '22 00:07 geoffromer

I like this, it's a lot cleaner and ':' is consistent with variable declarations

WarEagle451 avatar Jul 26 '22 16:07 WarEagle451

We've been trying to avoid angle brackets because they create very serious parsing problems. For example, a correct C++ parser has to implement substantial parts of C++'s name lookup and type checking rules, because in order to parse x<y, it has to figure out whether x is a template, in order to decide whether the < is a less-than operator or an open angle bracket.

That does make sense thank you for the explanation. Lexical parsing is a bit complicated. When working with golang, that was one of the things that threw me off. I am already starting to see based on the dislikes I got... there are more developers who don't like this idea.

The question is who is going to be your target users. People who come from typescript, kotlin, java, dart. Would want to use angle brackets whereas people who come from rust or go, might want to use square brackets. I'll leave it up to the discretion of the implementor.

dsriniv avatar Jul 26 '22 16:07 dsriniv

We've been trying to avoid angle brackets because they create very serious parsing problems. For example, a correct C++ parser has to implement substantial parts of C++'s name lookup and type checking rules, because in order to parse x<y, it has to figure out whether x is a template, in order to decide whether the < is a less-than operator or an open angle bracket.

Existing successful successor languages, TypeScript, Kotlin, and Swift (even Rust) all use <> for generics. Their design teams have considered the options carefully, and settled on <>. And they all handle it just fine. So calling it a very serious parsing problem is exaggeration. Also this is not C++ so we are not bound to handle <> as bad as C++.

Carbon should learn from existing design and implementation work of languages with the same goal.

emlai avatar Jul 26 '22 16:07 emlai

Carbon has a goal of being easy to parse for tooling, which has meant that we have considered and rejected angle brackets <...>, due to experience with the difficulties parsing them in C++.

The generics syntax is :!, meaning "passed at compile time", not square brackets [...], as described in #565 . Generic parameters passed explicitly, as in Slice(T) or Vector(T) are in round parens (...). The square brackets mark parameters whose value is deduced from the types of other parameters.

josh11b avatar Jul 26 '22 20:07 josh11b

2. Square brackets are more intuitive for Arrays...

All syntaxes are ugly: round brackets are more intuitive for calls. The issue with the square brackets is that if Carbon aims metaprogming, at some point there are chances that square brackets become completly ambiguous with indexing on a compile time list (let's say), so if you select type N in list A, it's not visually clear if it's an instantiation or a list extraction.

What should be discussed then becomes is more obvious, round or square is not the problem, the problem is to have an instantiation operator, like the bang in D, before the brackets, whatever is their shape.

SixthDot avatar Jul 27 '22 14:07 SixthDot

FWIW, I agree with what @josh11b has written here:

Carbon has a goal of being easy to parse for tooling, which has meant that we have considered and rejected angle brackets <...>, due to experience with the difficulties parsing them in C++.

The generics syntax is :!, meaning "passed at compile time", not square brackets [...], as described in #565 . Generic parameters passed explicitly, as in Slice(T) or Vector(T) are in round parens (...). The square brackets mark parameters whose value is deduced from the types of other parameters.

On the issue of using -> for function returns vs. : or something else, I think it is good to match C++ here which uses the same core symbol for its trailing return syntax.

Marking this as an issue for leads however as it is a concrete and specific question to use two alternative syntaxes.

chandlerc avatar Jul 30 '22 03:07 chandlerc

The : return type syntax is a popular request, and has the majority of upvotes in #1520 (comment). Given also that two existing successful successor languages (Kotlin and TypeScript) use it, there is considerable precedent.

The argument for -> is that function types look weird with the colon syntax: var func: (i32): i32, and so the arrow should be used in both places for consistency with var func: (i32) -> i32. But this is optimizing for the rarer case. Return type annotations and variable/parameter type annotations are way more common than function types, so it would make sense to optimize for a consistent syntax for them.

Well TypeScript actually uses func(): number { ... } for normal function definition and let func: (value: number) => number; for function types, so that would maybe also be an option? Just split it?

So fn func(): i32 { ... } for function definitions and I would suggest var func: (i32) -> i32; for function types? To probably be consistent with the future lambdas list.map { value -> value.x + value.y } if Kotlin-Style Lambdas are preferred...

DevNoteHQ avatar Aug 05 '22 01:08 DevNoteHQ

On the issue of using -> for function returns vs. : or something else, I think it is good to match C++ here which uses the same core symbol for its trailing return syntax.

I think there is some chance that we will want the same selection of options for function returns that we have for : -- in particular, for functions returning a generic / symbolic type we might want a ->! analogous to a :! binding, and for constexpr functions we might want something analogous to a template :! binding. I think we should wait until we're designing those facilities and then reconsider this question, and leave -> as-is for now.

zygoloid avatar Aug 09 '22 22:08 zygoloid

Marking this as decided with "not now" based on the discussion with leads and the explanation from @zygoloid and @josh11b above.

chandlerc avatar Aug 10 '22 01:08 chandlerc