The comparison here is from higher level (with semicolon and without semicolon)
All the languages that doesn't need semicolon above use Semicolon Inference, the method differ in variant. None telling to use Javascript method, basically end user doesn't has problem with any method, as long as it deliver. Hence the comparison is the resulted syntax. The solution is don't be Javascript, do things properly. There are plenty examples already in that many languages that I mentioned that may gives idea
I'm confused. What is all the ">,<" supposed to mean?
Getting people who don't know the language to suggest improvements is making little sense to me. It's like asking somebody you does not know English to suggest improvements to English. I'm sure they could do that until they have converted English into whatever language they do speak. No, human languages are grown and evolved by the people who speak it. Why not programming languages.
That is just emoticon to make conversation does not sound like serious interrogation. What is the problem with that?
No, it is called general user feedback. If you only take feedback from people that has 5 years+ Rust experience, it mostly consist bias that would miss guide the language, they think it looks ok because they already see something like that for 5 years+, but then when real new user comes, they say oh no this is not ok. Then it does not attract the fast majority user due to already happened to be like that. It is not like they are people with 0 programming experience, they are user that comes from other languages, already has programming experience. They know the borrowing system, just off by the syntax. And it is valid too, as even some already Rust user also say the syntax is not clean
Perhaps none. Except I'm old enough that I don't speak emoticon. Apart from ":)" which gets rendered as in the forum on my MacBook whereas ">,<" which I might have though was some weird syntax suggestion. It's not just me, nobody knows what it means. Google AI tells me it's all about pain, discomfort, frustration, embarrassment, or concentration. None of which sounds like what you have said there.
I have nothing against user feed back. But the word "user" there implies they have actually invested some time in using Rust, building things in Rust, finding out what Rust is all about and what its guiding profiles are.
gingerBill (creator of Odin) has a whole series of well written blog posts about PL syntax and whether it matters. I think the last post might be of particular interest.
I think here you want to have your cake and eat it, too. You are trying to build a custom syntax for Rust. Expecting tools like formatters and code highlighting written specifically for the Rust syntax to work with your custom syntax feels a bit too much to ask of such tools.
That is not part of the syntax. It is just emoticon. I intentionally avoid the emote is rendered (old style emot). Hence I use :<, :>, >,<, ^^, --, ^<. >,< looks like it is funny a prank etc
Not, knowing the reason why new user off from Rust is valid feedback. Why is my user leave my service? What is the problem they encountered?
I think I understand what you are getting at. Seems to me that pushed to extremes that requires Rust to adopt every syntax and semantics from every language any new user might be coming from. Which sounds like a nightmare to me.
I don't know from where you get the idea that this only happen in my custom syntax. It is the whole macro, as soon as characters enter macro, it becomes white colored. Having a toggle boolean to still apply the color to code inside macro regardless of its color matching is preferred compared to code inside macro becomes all white
I can understand the format part, tho it can be created to have boolean toggle for basic stuff too, like for auto complete of opening block, code inside matching opening and closing block is indended. But yeah this may can not be done for something like go to definition
Not, please don't keep exaggerating because none say every
Clearly I say about semicolon, and potential improvement to lifetime and nested type syntax. Instead of keep doing like that, start typing technical thing like what makes removing semicolon in Rust impossible with semicolin inference, etc
Now I just finished reading the article. He kinda missunderstood why removing semicolon and any other noise that can be removed scale well in readibily of many code. I would just put example as quick demonstration
struct Matrix {
data: Vec<Vec<i32>>,
}
fn with_semicolon(m1: Matrix, m2: Matrix, threshold: i32) -> Result<Vec<i32>, String> {
let check_dims = {
let r1 = m1.data.len();
let r2 = m2.data.len();
if r1 != r2 || r1 == 0 {
return Err("Dimension mismatch".to_string());
};
r1
};
let result = {
let mut row_sums = Vec::new();
let mut i = 0;
while i < check_dims {
let sum = {
let mut s = 0;
let mut j = 0;
let c1 = m1.data[i].len();
while j < c1 {
let val1 = m1.data[i][j];
let val2 = m2.data[i][j];
s += val1 * val2;
j += 1;
};
s
};
let filtered_val = {
if sum > threshold {
let adjusted = sum - threshold;
adjusted
} else {
0
}
};
row_sums.push(filtered_val);
i += 1;
};
row_sums
};
return Ok(result);
}
fn without_semicolon(m1: Matrix, m2: Matrix, threshold: i32) -> Result<Vec<i32>, String> {
let check_dims = {
let r1 = m1.data.len()
let r2 = m2.data.len()
if r1 != r2 || r1 == 0 {
return Err("Dimension mismatch".to_string())
}
r1
}
let result = {
let mut row_sums = Vec::new()
let mut i = 0
while i < check_dims {
let sum = {
let mut s = 0
let mut j = 0
let c1 = m1.data[i].len()
while j < c1 {
let val1 = m1.data[i][j]
let val2 = m2.data[i][j]
s += val1 * val2
j += 1
}
s
}
let filtered_val = {
if sum > threshold {
let adjusted = sum - threshold
adjusted
} else {
0
}
}
row_sums.push(filtered_val)
i += 1
}
row_sums
}
Ok(result)
}
One thing that could help here is multi-line and nesting. You can coerce rustfmt to aid with this by adding some line comments. For example if you insert one all the way in the middle
I was not trying to exaggerate. Rather just thinking bout what could happen if what you have suggested is pursued to extreme. Where do int stop?
First we get rid of semicolons to please the semicolon allergic. How about getting rid of those curly braces and use white space block delimiting, plenty of people would like that? But what about all the people who prefer keyword delimiting, like "if"...."else".... end" or some such, many people like that. And so on and so on.
None say curly bracket etc, I clearly mentioned to keep curly bracket. That is exaggerate, because I picked and said about thing that end in good result on user space code carefully, yet you spouting something that I didn't say at all. Say thing about the one that I propose like, or the discussion is not usefull, just going ford about something that is not even be talked about
You just made me remember, I also want to propose macro sugar for if else
let val = swap!(condition, val if true, val if false)
let val = swap!(condition, val if true, val if false)
let val = swap!(condition, val if true, val if false)
The name can be anything. It only accept condition and literal value/literal variable. Because this one is ugly for that case
let val = if condition { val if true } else { val if false };
let val = if condition { val if true } else { val if false };
let val = if condition { val if true } else { val if false };
Aditionally I would like to have annotation that will deny code that produce jump instruction, suct as
// compile error: using jump inside no jump. This code `b.push(new)` produces jump
no_jump! {
if a > 10 {
let new = a * 2;
b.push(new);
} else {
let new = a * 4;
b.push(new);
}
}
// no compile error
let new = no_jump! {
swap!(a > 10, a * 2, a *4)
}
b.push(new)
That is pretty usefull, so I can start commanding the CPU what to do because I can produce the instruction that I want deterministicly. Will make producing auto vectorized code very easy, no more uncertain guessing without seeing the assembly 1 by 1 for 1000 lines+ code
I'm late to respond so I'm probably repeating something others have pointed out, but still...
The point is that syntax and semantics go hand in hand, so you risk throwing out the baby with the bathwater. Lifetime annotations are there to disambiguate where references come from, for example. They can already be skipped when it's obvious.
Even the semicolon had a meaning, as an expression separator. Removing it makes it unclear if the last expression is the return expression of a block or not, so you would likely need another keyword for that, or use break.
For example
{
doSomething();
}
is equivalent to
{
doSomething();
()
}
so if the semicolon is removed, does that also mean doSomething() is the last expression? Or do we change blocks to need special syntax to return values other than ()?
// Does this return anything?
// Is it an error if the functions return different types?
if x {
doSomething()
} else {
doSomethingElse()
}
From what your comment, I can surely tell you haven't read my previous comments. Because none is saying to remove lifetime, but introduce clearner lifetime syntax. If I propose to remove lifetime, I wouldn't do this whole lifetime sugar thing. None is saying removing semicolon in the sense of removing it, I describe it from user point of view that typing semicolon is not required, then Rust handle the semicolon automatically (semicolon inference) as the discussion talk about semicolon inference above. See many other languages that uses semicolon inference that I mentioned, or just googling yourself what languages that uses semicolon inference. If you realize, last return has clear pattern like I mentioned before, it only happen at last, when there is assignment operator on the left + before the end of the most top parent scope that is assigned to said assignment operator, and rhe 2nd is before the end of function block. Clearly determistic algorithm can be built for it. If you are confused, here is the visualization
// search the latest line of block A before end }
// if it is an other block, visit and search the last again until no longer a block
// take the latest code before }
// if it is literal value/variable, don't add semicolon
// if it is function call that has return value, don't add semicolon
let a = if 1 == 1 { // parent block that is assigned to assignment operator, lets call it block A
if 2 == 2 { // child block, lets call it block B
let b = 3
b * 2
}
} else {
2 * 4
}
// if it is latest code before }
// and the function has return type
// and it is 1 of literal value, literal variable, or function call that return value, eg get_number()
// don't add semicolon
fn abc(a: i32) -> i32 {
let b = a * 2
b * 4
}
The algorithm can be improved if there is room, but that is in general. It is not like it doesn't has pattern, it clearly has pattern
First, let me just say I'm not attacking your ideas. I'm just here to bring some related reading material and am arguing for why it's relevant.
From what your comment, I can surely tell you haven't read my previous comments. Because none is saying to remove lifetime, but introduce clearner lifetime syntax. If I propose to remove lifetime, I wouldn't do this whole lifetime sugar thing.
I probably misunderstood what you meant with the syntax not being "clean" and mentioning lifetimes afterwards. My argument wasn't really about any specific piece of syntax anyway, but rather to say that the blog post is about both syntax and semantics together. Changing the syntax can affect the semantics. That's it.
None is saying removing semicolon in the sense of removing it, I describe it from user point of view that typing semicolon is not required, then Rust handle the semicolon automatically (semicolon inference) as the discussion talk about semicolon inference above. See many other languages that uses semicolon inference that I mentioned, or just googling yourself what languages that uses semicolon inference. If you realize, last return has clear pattern like I mentioned before, it only happen at last, when there is assignment operator on the left + before the end of the most top parent scope that is assigned to said assignment operator, and rhe 2nd is before the end of function block. Clearly determistic algorithm can be built for it.
Sure, that may work, but as exemplified by the video @Schard linked, the semicolon is a signal of intent and incentivising the programmer to not signal that intent may come with mismatched expectations. I don't know how many languages with last-expression returns and static type systems there are that also have semicolon inference, but maybe it's fine in practice.
Let me just finish by bringing up another piece of syntax that I know you didn't ask about; the mut keyword. It was once proposed to be removed from patterns (let mut a =...; etc.) and to rename &mut. It was however kept around because it is one such signal of intent and people wanted to have that compiler error when it's missing and the variable is mutated. Just a piece of Rust history if you are interested: Focusing on ownership · baby steps
If you have read my comments now, you would know changing the syntax doesn't change the semantic. The information suct as the lifetime name, the tagged variable can be captured just fine. Tho I still don't find the best syntax arrangement combination yet, still looking for better one than the one I get. For now at least lifetime and generic declaration is separated cleanly
Then what is the point that you are trying to say? Are you trying to say that removing the semicolon using semicolon inference remove the intent?
If yes, I would answer it is not as I gave code demonstration above
It behave exactly like the current one, just be inserted by the compiler. As long as it is not last value with assignment operator on the left, or last value of function, it is auto semicolon insertion aka the value is discarded
The &mut has no correlation, this is all about removing semicolon noise or for better wording this is about turning off the semicolon from the screen, and later the compiler will insert it
Can we have a compiled and working actual Rust version of that for comparison. Preferably with variables rather that he hard coded numbers. As far as I can tell it cannot work as there is no "else" after the "if 2 == 2 "
That is not important. If you know the essensial thing of what that code is trying to explain, you would know adding an else does not make it tell different story. else { 20 } no different story, it is still last value of last child scope of last scope that is assigned to assignment operator =
Pseudo code is for telling the neccerery thing, to avoid noise. The else part of the parent already handle showing the else part, the true part is focused to showing the nested scope