Live data from Hacker News

Rust for JavaScript Developers – Functions and Control Flow

sheshbabu.com

41–50 of 78 posts

Re: Rust for JavaScript Developers – Functions and Control Flow

#41
> Arrow functions are a popular feature in modern JavaScript - they allow us to write functional code in a concise way.

> Rust has something similar and they are called “Closures”. The name might be a bit confusing (...)

This is in turn confusing to me!

I can't imagine a world where you know JS and especially "functional" JS, but haven't heard of the term "closure".

"Arrow functions" are just sugar. They don't have any special meaning. All functions in JS, regardless of whether they are declared, assigned, returned etc., are closures and capture their environment.

Similarly a normally declared function in Rust are first class values as well and for example can be passed into higher order functions.

Giving the benefit of the doubt, I assume that the author knows this and just wanted to introduce the term in a beginner friendly manner. But I think it would be less confusing to just use the term and link to an official documentation:

Rust: https://doc.rust-lang.org/book/ch13-01-closures.html

JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Clos...

Re: Rust for JavaScript Developers – Functions and Control Flow

#42
post #41

> Arrow functions are a popular feature in modern JavaScript - they allow us to write functional code in a concise way. > Rust has something similar and they are called “Closures”. The name might be a bit confusing (...) This is in turn confusing to me! I can't imagine a world where you know JS and especially "functional" JS, but haven't heard of the term "closure". "Arrow functions" are just sugar. They don't have a…

> "Arrow functions" are just sugar

This statement is incorrect. There are important differences between arrow functions and regular function.

> An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re: Rust for JavaScript Developers – Functions and Control Flow

#43

Earlier quoted context omitted.

Rust 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.

what about `fn(args) => exp`? Can be simplified as `fn arg => exp(arg)` for simple ones..

That 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.

Re: Rust for JavaScript Developers – Functions and Control Flow

#44
post #34

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…

Rust 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.

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.

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.

Re: Rust for JavaScript Developers – Functions and Control Flow

#45

Earlier quoted context omitted.

Rust 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.

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. 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.

> 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.

Re: Rust for JavaScript Developers – Functions and Control Flow

#46

Earlier quoted context omitted.

Rust 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.

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. 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.

Many 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(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.

Re: Rust for JavaScript Developers – Functions and Control Flow

#47
post #41

> Arrow functions are a popular feature in modern JavaScript - they allow us to write functional code in a concise way. > Rust has something similar and they are called “Closures”. The name might be a bit confusing (...) This is in turn confusing to me! I can't imagine a world where you know JS and especially "functional" JS, but haven't heard of the term "closure". "Arrow functions" are just sugar. They don't have a…

> "Arrow functions" are just sugar This statement is incorrect. There are important differences between arrow functions and regular function. > An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

I include this in sugar as in:

You can refactor an arrow function into a specific regular function but you usually end up with something more verbose.

Or in other words you can express all things "arrow" before it existed. Which is exactly what we did before they were adopted. And we still in fact do, just automated by transpilers like Babel[0].

But more importantly, in the context of the article: all functions in JS are closures, regardless of how you write them.

[0] https://babeljs.io/docs/en/babel-plugin-transform-arrow-func...

Re: Rust for JavaScript Developers – Functions and Control Flow

#48

I just converted a relatively simple node.js program to Rust (because the native libusb bindings for node.js crash immediately on Windows 7 64-bit) Rust made me worry about a lot more than I wanted to. Threads, locking, mutability. What was 80 lines of: 1. open USB device, get handle 2. start a WebSocket server, accept clients 3. proxy incoming USB device traffic to all WebSocket clients 4. proxy incoming WebSocket t…

Yeah part of this is definitely true - Rust is more more verbose about things you often don't really care about (e.g. `String`/`str` in code that only runs once - who cares?).

But a lot of the extra effort in writing Rust code is about moving runtime errors to compile time. It's like static types - more effort writing it but you don't spend ages debugging typos at runtime. I've had way more instances of spending several hours writing complex code and having it work first time in Rust than in any other language. In C++ it's so rare it makes me extremely suspicious when it happens (did I actually recompile?), whereas in Rust I'm almost starting to expect it.

Re: Rust for JavaScript Developers – Functions and Control Flow

#49

I just converted a relatively simple node.js program to Rust (because the native libusb bindings for node.js crash immediately on Windows 7 64-bit) Rust made me worry about a lot more than I wanted to. Threads, locking, mutability. What was 80 lines of: 1. open USB device, get handle 2. start a WebSocket server, accept clients 3. proxy incoming USB device traffic to all WebSocket clients 4. proxy incoming WebSocket t…

It sounds a bit like you tried to write Rust like you do JS. Rust is “move” by default. Passing ownership of a variable to callbacks requires making sure you have the correct types along the way, especially if you want to mutate. It can be easier in many cases to only deal with “owned” data in Rust at first. Clone a lot, and so on.

rust is for losers

Re: Rust for JavaScript Developers – Functions and Control Flow

#50
post #22

Earlier quoted context omitted.

True, or even: Cond1 // if this ? Result1 // return this : cond2 // else if this ? Result2 // return this : cond3 // else if this ? Result3 // return this : ResultElse // else return this

Goodness me that has potential to become something truly hideous.

It's funny how people have so many different preferences for ternary formatting. I can't think of any other operator that would have tens of different format prefs.
Post reply on HN