5 ms·
Now it is official: I like (modern) JavaScript. I am a C# guy and every time I see modern Rust, C++ or Go syntax I am really surprised by its deviation from th
by oaiey 6y ago
Now it is official: I like (modern) JavaScript.
I am a C# guy and every time I see modern Rust, C++ or Go syntax I am really surprised by its deviation from the norm (which is interestingly no longer C but a hybrid between JS/Java/C#). I mean why different Rust syntax for closures and functions. || vs ().
On the other hand, the linage is not Java/JS/C# to Rust but C/C++ to Rust. Considering that, it is an improvement.
- chrismorgan 6y agoRust has a philosophy of easy machine and human parsing. ECMAScript-style `(…) => …` requires that you get to the => before you know whether the (…) is a parenthesised expression or function arguments. With `|…| …`, you know you’re dealing with a closure immediately because there’s no unary pipe operator.
- entha_saava 6y agowhat about `fn(args) => exp`? Can be simplified as `fn arg => exp(arg)` for simple ones..
- chrismorgan 6y agoThat works for JavaScript, because functions are just functions. But in Rust, closures are different from functions, though they all implement the Fn, FnMut or FnOnce traits. Functions don’t close over any state (so you can cast them to a 'static function pointer), while closures can. Using the fn keyword for closures would thus muddy the conceptual waters—though you could argue that the names of the Fn* traits has already done that—and potentially hinder future language design. I feel a stronger argument is that it’s also markedly longer and more visually noisy; `x.map(|x| …)` is seven characters shorter than `x.map(fn x => …)` and eight than `x.map(fn(x) => …)`, and to some extent words are more distracting than symbols. Pipes isn’t perfect, but given the consistent philosophies of the Rust language, I am not aware of any better option. But it’s definitely a fairly subjective matter.
- esperent 6y agoWhat's the reason for including ease of machine parsing? Aside from the fact it might make the compiler slighty easier to write I guess. I'm sure that code that's easy for machines and humans to parse is harder for humans to parse than code where humans are the first class citizens.
- Tuna-Fish 6y ago> What's the reason for including ease of machine parsing? Aside from the fact it might make the compiler slighty easier to write I guess. Most of the designers have spent a long time writing C++, and C++ is famously extremely hard to parse for machines, and this has caused a lot of problems for compiler/language authors. It's normal for people to overcorrect when they have real trouble with something. > I'm sure that code that's easy for machines and humans to parse is harder for humans to parse than code where humans are the first class citizens. I'm not sure at all about that. Making syntax that is easy for machines to parse mostly means that your syntax needs to be wholly context-free and low-lookahead. Both these features help people too, even if they result in more different kinds of characters in your source code.
- chrismorgan 6y agoMany languages require arbitrary lookahead in order to parse code. (Some are even worse, e.g. C++ requires a full compiler to parse it because of the question of whether `(a<b, c>(d))` is calling a generic function a, or doing two comparisons; and Perl is unparseable, you’ve got to run it before you can figure out how certain things should be parsed.) Rust’s philosophy has been to avoid that, and make it simple to parse, because that helps tooling and people alike. Most people don’t see why this is a big deal. Here’s why: humans parse code when they’re reading it in a very similar way to how computers do. This holds true of natural language parsing, too, and is much better documented in that industry. If it’s hard or takes longer for a computer to parse it, it’s very likely to be hard for a human to parse it. If you have fat arrow syntax, you need to skip ahead on the line to find it to confirm that what you’re looking at is a closure. Pipes say from the very start “this is a closure”. This could be said to be why Rust uses the `let` keyword too, which is theoretically unnecessary (though you might need something to replace it in a small fraction of cases). Not only does it make parsing way easier for machines (in a way that makes extending the language grammar later much easier too, but that’s part and parcel of the parsing philosophy), it makes the intent of the line immediately clear to humans.
- nicoburns 6y agoThe Rust closure syntax come from Ruby: https://blog.appsignal.com/2018/09/04/ruby-magic-closures-in-ruby-blocks-procs-and-lambdas.html#:~:text=A%20closure%20is%20a%20first%2Dclass%20function%20with%20an%20environment.&text=The%20closure%20will%20retain%20its,of%20blocks%2C%20procs%20and%20lambdas https://blog.appsignal.com/2018/09/04/ruby-magic-closures-in....
- deleuze 6y agoSyntax is the least interesting thing about a language (unless it's a lisp ^^). Why not different syntax for closures?