Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upSwitch `<>` back to `[]` #148
Conversation
thehydroimpulse
added some commits
Jul 1, 2014
lilyball
reviewed
Jul 1, 2014
| // Possible syntax for HKTs. | ||
| pub trait Monad[M[T]] { | ||
| // ... | ||
| } |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
How does this bring the ability to have nicer syntax for HKTs? Wouldn't the example be exactly the same when written like this?
pub trait Monad<M<T>> {
// ...
}
This comment has been minimized.
This comment has been minimized.
thehydroimpulse
Jul 1, 2014
Author
That is one syntax proposal for HKTs (following in Scala's footsteps) which is ok (There are better alternatives that focus more on inference). I find [] a lot more composable than <> (i.e., you can nest them without it being cryptic to read).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
Define "cryptic to read". The nesting properties of [] and <> are identical. You personally may simply have more experience reading nested [] due to being used to Scala. Me, not being a Scala programmer, very rarely encounter nested [] and I find there to be no benefit at all over <>.
This comment has been minimized.
This comment has been minimized.
thehydroimpulse
Jul 1, 2014
Author
Yes, imo, [] is much nicer to read than <> without being exposed too much myself (to the [] syntax).
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
I think that this claim should be removed—it has no substance apart from the previous claim, is subjective and is not dealing with a concrete situation (HKT is far future).
This comment has been minimized.
This comment has been minimized.
lilyball
reviewed
Jul 1, 2014
| ```rust | ||
| fn parse['a, T: Encodable[Encoder['a], IoError]](value: T) { | ||
| // ... | ||
| } |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
By what criteria are you claiming that this "composes much better"? It's literally the the same number of symbols, arranged in the same fashion, with the same basic properties (balanced pairs of some form of bracket), with the only only difference being one uses square brackets and one uses angle brackets.
You seem to be taking it as a given that what you've stated is true, but without providing any evidence whatsoever, I'm unconvinced that this provides a readability benefit.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
thehydroimpulse
Jul 1, 2014
Author
Nesting them (i.e., T: Encodable[Encoder['a], IoError] vs T: Encodable<Encoder<'a>, IoError>)
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
thehydroimpulse
Jul 1, 2014
Author
It's not the amount of nesting, it's that [] separates each piece a lot better (imo) than <>, resulting in it being easier to read.
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
@thehydroimpulse Then express it that way—for that is different from what people will understand by the other things you’ve said here. Incidentally, I agree with you completely on that claim.
This comment has been minimized.
This comment has been minimized.
chris-morgan
reviewed
Jul 1, 2014
| } | ||
| fn main() { | ||
| let something = foo[int](); |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
This is problematic, colliding with indexing—indexing requires an expression inside the [], specifying generic parameters requires a type or types. Thus I suggest that foo::<int>() is changed to foo::[int]() rather than foo[int](), for now at least.
lilyball
reviewed
Jul 1, 2014
| } | ||
| ``` | ||
|
|
||
| 4. There's precendence for it. Scala's syntax for generics is awesome. It imposes very little effort when reading and understanding. |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
Not being a Scala programmer, I am unfamiliar with Scala's generics syntax. And again, you are stating without evidence, or without even providing an example of Scala's grammar, that it's more readable.
This comment has been minimized.
This comment has been minimized.
lilyball
reviewed
Jul 1, 2014
|
|
||
| 4. There's precendence for it. Scala's syntax for generics is awesome. It imposes very little effort when reading and understanding. | ||
|
|
||
| 5. Somewhat related to the first point in that it would bring a consistent syntax for generic everywhere. No more `foo::<>()` that tends to confuse people (not those already aware of the syntax, of course). |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
We can't get rid of foo::<>(). The exact same problem that required us to use that syntax would require us to use foo::[]() with the new syntax. Which is to say, we use ::<> in order to disambiguate the < token between being an operator and being a generic parameter list, and we'd have the exact same issue with [ (as that's also the token that starts a subscript operation).
lilyball
reviewed
Jul 1, 2014
|
|
||
| 4. There's precendence for it. Scala's syntax for generics is awesome. It imposes very little effort (I think) when reading and understanding. | ||
|
|
||
| 6. Because it's consistent and has no ambiguities, one can finally use motions like `%` in Vim (and alternatives in other editors.). |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
I have never had an issue using % in Vim. We do not support the use of < or > as an operator inside of a generic type parameter list, which means there is no problem finding the matching < or > when using %.
lilyball
reviewed
Jul 1, 2014
|
|
||
| Recently there has been a lot of talks on simplifying the syntax. Starting from removing the sigils `@` and `~` and making lifetimes less syntax heavy (through various proposals). I think changing the current generic syntax to `[]` will make it that much better and clearer (I think `[]` is much easier to read). | ||
|
|
||
| 1. We would remove the current ambiguities surround the current syntax `<>`. That means, we could be able to have: |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
What ambiguities? You haven't described any.
The only ambiguity I know of is the one requiring the use of foo::<int>(), and the change to [] does not resolve that. As @chris-morgan already said, your code example here needs to still be foo::[int]() to be unambiguous.
This comment has been minimized.
This comment has been minimized.
|
One of the key benefits of using I am surprised by how much easier I find
Using |
This comment has been minimized.
This comment has been minimized.
|
I don't buy the matching argument. I will readily admit that it's true that That said, I appear to have broken something, because I swear it used to work for me out of the box, but right now |
This comment has been minimized.
This comment has been minimized.
|
Big |
chris-morgan
reviewed
Jul 1, 2014
| } | ||
| ``` | ||
|
|
||
| 4. There's precendence for it. Scala's syntax for generics is awesome. It imposes very little effort (I think) when reading and understanding. |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
After the first sentence, this is pure subjectiveness and not distinct from the earlier points.
What is of note here is this. At the time when Rust changed from [] to <>, there was no known precedent in a C-style language for []-generics: C++ and Java, for example, used <>. Since then, [] has been adopted in at least one fairly popular language, Scala.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I think the original issue (from what I heard, don't quote me) to switch was because |
lilyball
reviewed
Jul 1, 2014
|
|
||
| Recently there has been a lot of talks on simplifying the syntax. Starting from removing the sigils `@` and `~` and making lifetimes less syntax heavy (through various proposals). I think changing the current generic syntax to `[]` will make it that much better and clearer (I think `[]` is much easier to read). | ||
|
|
||
| 1. `[]` is easier to type than `<>`. |
This comment has been minimized.
This comment has been minimized.
lilyball
Jul 1, 2014
Contributor
I disagree. It actually takes less hand movement for me to type <T> on my US English keyboard than for me to type [T].
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
@thehydroimpulse You should specify on most keyboards; you simply can’t make such assertions without appropriate guard conditions.
@kballard On the standard US English keyboard, [] don’t require the Shift modifier to enter them whereas <> do. The impact of this is reduced for [ as it will normally be followed by an uppercase letter, incidentally, but it won’t for ['a and it won’t for ] unless the last character was also uppercase. This, I presume, is what you are referring to here: for <T> you can just hold the Shift key for all three characters, whereas with [T] you can’t. I accept this case. Still, in most cases I find [] a little easier to type than <>.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
To parse this, when we see a
Could be either indexing or taking the value of a generic function, substituting a type parameter, but you won't know. |
This comment has been minimized.
This comment has been minimized.
|
@cmr Yes there's some ambiguities around arrays with this proposal. |
thehydroimpulse
added some commits
Jul 1, 2014
chris-morgan
reviewed
Jul 1, 2014
|
|
||
| 1. `[]` is easier to type than `<>` on *most* keyboards. | ||
|
|
||
| 2. `[]` delimeters are always matching. |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
This needs to be clarified, with reference to the comparison operators < et al. It should be merged in with the sixth point, the practical benefit of this.
This comment has been minimized.
This comment has been minimized.
chris-morgan
reviewed
Jul 1, 2014
|
|
||
| This is a very easy change to make. | ||
|
|
||
| ## Downsides |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
thehydroimpulse
added some commits
Jul 1, 2014
chris-morgan
reviewed
Jul 1, 2014
|
|
||
| # Detailed design | ||
|
|
||
| This is a very easy change to make. |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
That’s… not much of a detailed design. How about saying something like “in type parameter lists, replace < with [ and > with ].” and giving examples of T<U, …> and f::<T, …>()?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
chris-morgan
reviewed
Jul 1, 2014
| } | ||
| ``` | ||
|
|
||
| 3. There's precendence for it. Scala's syntax for generics uses `[]`. At the time when Rust switched form `[]` to `<>` there was no precedence in a C-style language for `[]` generics. That's no longer true. |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jul 1, 2014
Member
s/form/from/
I’d also reword this; perhaps something like “4. At the time when Rust switched from [] to <> there was no precedence in a C-style language for [] generics; this no longer true: Scala is an example of a language that has become fairly popular recently and which uses [] for its generics syntax.”
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@cmr: |
This comment has been minimized.
This comment has been minimized.
|
We can't use |
This comment has been minimized.
This comment has been minimized.
ghost
commented
Jul 2, 2014
|
@kballard () for indexing interests me quite a bit. Can you please elaborate your reasoning why Rust can not apply it? Can you tell an example where there is a need to be able to both call and index a value? |
This comment has been minimized.
This comment has been minimized.
|
As far as the ugliness of the current type application syntax is concerned, how do people feel about, instead of,
writing
? I don't believe It's not shorter, but it's more readable and perhaps less ugly. |
This comment has been minimized.
This comment has been minimized.
bachm
commented
Jul 2, 2014
|
@glaebhoerl I don't like |
This comment has been minimized.
This comment has been minimized.
simias
commented
Jul 2, 2014
|
@glaebhoerl how would that scale for more complex declarations? Do you put type in front of each parameter? What about nesting? Also rust might end up adding stuff like constant integer parameters and things like that, "type" wouldn't fit those semantically. What would you do with lifetime parameters? I guess you could say there're a type but that's stretching it a bit IMO. I don't think this solves anything really, I don't like the |
This comment has been minimized.
This comment has been minimized.
bachm
commented
Jul 2, 2014
|
|
This comment has been minimized.
This comment has been minimized.
|
I never implied that it's perfect, only that it might suck less. @simias I was thinking the rule would be that if providing a kind annotation ( |
This comment has been minimized.
This comment has been minimized.
adrientetar
commented
Jul 2, 2014
|
|
This comment has been minimized.
This comment has been minimized.
simias
commented
Jul 2, 2014
|
@adrientetar that's more of a rationalization really. I mean, you can think about it that way but to me But anyway, this is off topic since this proposal still requires |
This comment has been minimized.
This comment has been minimized.
|
@almale RFC 34 defines traits that can be used for implementing the indexing operator on arbitrary types (we actually already have an existing trait for this, but it's badly-designed and nobody uses it). RFC PR #114 provides unboxed closures by adding traits to represent function calling. This allows arbitrary types to be callable (as Implementing both traits on the same type allows a value of that type to be both indexable and callable. This requires that the indexing and calling operators be syntactically distinct, which means |
This comment has been minimized.
This comment has been minimized.
|
@almale I don't know what a real-life example of such a type will be, but the fact remains that our traits allow for it, and therefore Furthermore, you cannot resolve that by getting rid of indexing in favor of using calling as the indexing operator, because that doesn't support the distinction between immutable and mutable indexing, or the ability to assign to an index. Note that while the callable traits have variants for mutable and immutable, one type is not allowed to implement both (or more accurately, |
This comment has been minimized.
This comment has been minimized.
|
C uses [] for index arrary. I don't think there is enough reasons to change
|
This comment has been minimized.
This comment has been minimized.
boggle
commented
Jul 3, 2014
|
Hi, could you explain the use case for this? I can't see it. While scala Stefan
|
This comment has been minimized.
This comment has been minimized.
lexspoon
commented
Jul 3, 2014
|
Interestingly, RFC #34 and RFC PR #114 are quite similar to how Scala approaches these problems. One difference is that Scala doesn't require using any particular trait; a type just defines methods of the appropriate name if it wants to use I would think, as @boggle suggests, it's up to you whether you want to have objects that are callable and indexable with a different meaning for each one. If that's more of an accident than an actual goal, then couldn't you just use the same set of names for both cases? In rvalue position, expand to ( Not to say that it's right because Scala does it, or even that it's right at all for Rust. The two languages run into similar challenges due to both trying to bring functional programming to mainstream ecosystems, so I thought I'd share. |
glaebhoerl
referenced this pull request
Jul 13, 2014
Closed
Turn capitalization conventions into language rules for 1.0 #154
This comment has been minimized.
This comment has been minimized.
DAddYE
commented
Jul 22, 2014
|
In merit to this issue see this: http://www.reddit.com/r/rust/comments/2bbeqe/it_started_out_with_great_enthusiasm_but_ended_up/ We had a small conversation here about one statement from the author: http://www.reddit.com/r/rust/comments/2bbeqe/it_started_out_with_great_enthusiasm_but_ended_up/cj3v5x6 Anyway, I'm one of them that wish we could switch back to I don't see that much the point that of
|
This comment has been minimized.
This comment has been minimized.
flying-sheep
commented
Jul 22, 2014
|
I really think readability should beat familiarity. Your example is a good one, as it's very jarring to mentally parse, because There are angled brackets in Unicode, but (understandably) we don't want to The characters <> really only serve as operators, not fake brackets. |
This comment has been minimized.
This comment has been minimized.
|
I must admit to being more sympathetic now to the "it looks nicer" argument for |
This comment has been minimized.
This comment has been minimized.
DAddYE
commented
Jul 22, 2014
|
@kballard regarding that, I'll quote JouMaSePLoS:
Also, as others pointed out, scala use However, keep in mind that a language syntax last 20+ years, so I really hope we couldn't carry for 40 years the operator |
This comment has been minimized.
This comment has been minimized.
That's quite a good point. Though I don't agree with the implication of the latter half of the comment that |
This comment has been minimized.
This comment has been minimized.
I was very confused when I first saw Scala code using Once again, I think Parentheses are in fact the most intuitively correct option, as generic types, or types parameterized over types, in a very precise sense are like functions, or values parameterized over values. (Or not even "like": they are functions at the type level. More specifically, they're the same thing on the type level as enum variants are on the value level. General type functions, or associated types, are the precise analogy for general value-level functions, of which "normal" generic types are a specific case in the same way that enum variant construction is of function calls.) It's not by accident that Haskell shares the same syntax for function calls, data construction (enum variants), and type construction (generics). (As a side note: I think we could then use |
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl We can't use |
This comment has been minimized.
This comment has been minimized.
|
In a language that had made different fundamental choices about inference and overloading, It's not considered a bad thing in any language that supports operator overloading that it's possible to overload both 'function call' and 'index' operators depending on what your intention is. And even though maps are functions, templates are still more like maps than they are like other functions. |
This comment has been minimized.
This comment has been minimized.
"Can't" is a strong word. D does it. (They use I think it's much less bizarre than the clash of |
This comment has been minimized.
This comment has been minimized.
DAddYE
commented
Jul 22, 2014
|
IMHO both |
thehydroimpulse
restored the
thehydroimpulse:type
branch
Jul 29, 2014
This comment has been minimized.
This comment has been minimized.
|
@DAddYE Forgot to reply. I think a member of the core team should way in before this is reopened. I don't want to continue a needless bike shed for the sake of it with a low-chance it's going to be taken seriously. |
thehydroimpulse commentedJul 1, 2014
Here we go.
Thoughts?