1) \ is usually taken for escapes, | is non-directional
and therefore doesn't work with arbitrary nesting, and
/ causes the same problems as <.
> Keep in mind Rust goal almost from the start was
> something that is familiar to a people that worked
> with Gecko engine. With that in mind, I can't think
> of a similar family language that did this.
Isn't this the classic Golang emergency excuse?
"Golang was built by Google engineers to solve Google's
problems, so could you please kindly **** off, dear
non-Googler."
Nobody claims that <> isn't "familiar". People are claiming
that <> isn't very good, and they are correct with that.
Those languages which made <> "familiar" picked <> because
they added templates/generics/... after the fact and tried
to bolt them onto an existing language without breaking all
existing code.
<> was usually the least worst option for those languages.
It doesn't follow that a language designed from scratch
should adopt <> without thinking, because there are better
alternatives when designing a language which has Generics
from day 1.
> You know what happens when you call Index/IndexMut.
> To say it isn't so, is outright fallacious.
extern crate rand;
use std::ops::{Index,IndexMut};
use rand::random;
fn main() {
let mut arr = MyFunnyArray { arr: [0,1,2] };
println!("arr is {:?}", arr);
arr[5] = 23;
println!("arr is {:?}", arr);
}
#[derive(Debug)]
struct MyFunnyArray {
arr: [u32; 3]
}
impl Index<usize> for MyFunnyArray {
type Output = u32;
fn index<'a>(&self, _index: usize) -> &u32 {
&self.arr[random::<usize>() % 3]
}
}
impl IndexMut<usize> for MyFunnyArray {
fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut u32 {
self.arr[random::<usize>() % 3] = random();
&mut self.arr[random::<usize>() % 3]
}
}
Looks pretty arbitrary to me.
2) > No we don't. I think having user and built-in
> defined types is perfectly ok.
Sure, but how is this even related to the topic?
4) > Related yes, same no. In same way i32 and u32 are
> related but not the same.
As you might see, they are called i32 and u32, not i32
and UnsignedInt4Bytes.
> As I said in previous question having some subset of
> language be unable to modify is IMHO a good thing.
I'm not sure what you are trying to argue here.
Consistency has nothing to do with being "able/unable to
modify". People are unable to modify most types, it
doesn't matter if they come from a third-party crate or
the core language.
6/7)
> They can't. You can tell by mutability of array which
> one will be called and which one will be returned.
> You CAN'T EVER change type of mutability of result.
Not sure what you suddenly try so say with "you can't
modify this", "you can't mutate that".
As shown in 1) [] can do whatever the developer implements.
Sure, the usual language rules apply, I think nobody
disagreed on that.
9) > Whenever I see macros/operator overload/syntax being
> given too much freedom, it always ends up with
> incomprehensible DSL-s that you can't disentangle from
> regular code.
Yes, that's exactly the concern I'm raising here, because
that's what Rust is encouraging.
10) No, not really. Just compare the issues caused by using <>
vs. other approaches. 1) You basically have both () and [], wasting one of the scarcest
resources in syntax (brackets).
Some people might argue that getting a value from an array is totally
different from getting the same value from a function or a map, and
deserves special syntax. If we look at languages which did away with
this made-up difference we see that pretty much no person is missing
it.
Even if you disagree with this reasoning and consider arrays to be
something very special, deserving its own syntax – guess what? Rust
developers introduced the traits Index and IndexMut, so all the great
ideas about some type being special and knowing what happens when you
read [] went straight out of the window.
If we dig deeper and try to understand why they did something so
astoundingly mis-designed, we basically hit an interesting issue:
They overloaded their [] operator to do two completely different
things, depending on whether there is an & in front.
Thing A: return the value at the given index
Thing B: return an address pointing into the indexed data
This of course doesn't translate well into the () syntax, given that
Rust devs are proud that they don't support overloading.
(I guess []'s overloading doesn't count for some reason ... and doing
the little dance with traits doesn't count either.)
Taking a step back, if it would have been considered acceptable to
pick two different names for doing two different things, the whole
issue wouldn't exist, e. g.:
Thing A: values(1)
Thing B: values.at(1)
2) Yes, we agree. Having different sets of rules for a) language
designers and b) language users has shown consistent results:
It never worked out.
3) Yes. I have nothing against terse syntax, it should just be
consistent. (I favor not abbreviating things though, because it's
difficult to be both terse and consistent, considering that things
can be abbreviated in more than one way.)
4) Yes, I know what they do. I just thought it was a nice example of two
related constructs having different casing style and abbreviation
style.
6/7) See 1). The sad thing is that [] can do whatever the developer
wants. All guarantees went out of the window with Index/IndexMut.
9) What I meant was that not every macro wants to define some weird
language DSL. There are plenty of things which only exist as macros
because the language lacks varargs. (vec! for instance.)
If the language ever adds varargs, vec! can't just stop being a macro,
because that would break source compatibility: They would need to keep
the macro version of vec and introduce a new non-macro version of vec,
and hope people migrate from vec! to the "new" vec.
It's a design which makes the common 90% suffer for the benefit of the
most complex 10%. Sometimes it is worth it, but in this case I think it is
not.
10) I had the combination of picking a symbol which is both hard to read and
hard to parse in mind.
Every language that chose <> has weird cruft and therefore it shouldn't
haven been too surprising that Rust is also suffering issues, but in
Rust's case the problems have been shokingly severe. There are loooong
discussions about it if you want to read them. (So it's not just me.)
11) Sorry, I meant structs.
12) URLs are an option. There are also alternatives. I think the essence is
that it's possible to deal with these issues without entering Java's
tld.mycompany.mycontinent.mygroup.myproject.mydogsmiddlename madness.
I hope this cleared some things up. :-) - "Having two different ways to call/invoke/execute stuff
made it much simpler to learn the language."
- "Making the casing of types inconsistent really helps
when reading code."
- "Dropping random characters in functions and types made
me feel at home coming from C! I would be terribly
confused if ptr was called pointer, vec vector, fmt
format, iter iterator or rt runtime. The only thing I
don't like is FromStr, it should really by FrmStr
instead! .. I love str's rsplitn btw!"
- "Calling Strings Strings and String views str ... that
makes a lot of sense!"
- "Having used both <> and [] extensively, <> is much
more readable."
- "It was a really great idea to have special syntax for
arrays, so the language designers could overload []
with two completely different meanings."
- "Having both () and [] available is great because you
can write code where foo(x) and foo[x] do different
things!"¹
- "Not having varargs really worked out! Nevermind that
most popular macros exist solely to emulate varargs!"
- "Despite most macros not needing the do-whatever-
you-want syntax, let's require ! for all of them. This
way, macro writers don't have any reason left to try
making their macros behave predictably! Isn't it great
that they can just claim 'you knew that all bets where
off when you wrote that !, so stop complaining!'
instead of fixing their macro?"
- "Fucking up Generics so badly that it requires
different ways of writing them depending on the
context really paid off. It's certainly not an issue
which is hit by every person writing something Generic
for the first time."
- "Inventing unnecessary differences between modules and
objects is great, because it forces you to think
whether you need to use . or :: and breaks use-sites
of that code when migrating from one to the other."
- "Given all the lessons of terribly broken dependency
management systems out there – let's just ignore them
all and put every package in a global namespace ...
what could ever go wrong?"
The language could have been much better if Rust devs wouldn't have been so insecure and defensive, but now it's too late anyway. SQL: Pointless without Generics.
Cache layer: Pointless without Generics.
ORM: Pointless even with Generics.
Not sure if your examples are supporting your point.
Number of language features implemented in the last version:
Number of language features planned for the next version: