> if your email provider attempts to scan urls to see where they actually go you end up giving them an auth token
One way you can handle this is to place the token in the hash portion of the url (which doesn't get sent to servers during an HTTP request), and then have JS on the frontend send the token to your backend manually. As long as the email provider isn't scanning links via a headless browser that executes JS, this should work.
I agree with your point about email abuse though (although you still have to prevent bots from abusing email based password resets).
> Plus in most cases showing error messages too fast is terrible UX.
The solution to that problem is to debounce or throttle your error messages. That allows you to report validation issues to the user quickly, but not overwhelmingly fast, before sending a network request potentially across the Earth and back.
> The alternative is the npm hellscape where you have a package for "isOdd" and a package for "is even" that can break the entire ecosystem if the owner is disgruntled because everything depends on them.
The is-odd and is-even packages are in no way situated to break the ecosystem. They're helper functions that their author (Jon Schlinkert) used as dependencies in one of his other packages (micromatch) 10 years ago, and consequently show up as transitive dependencies in antiquated versions of micromatch. No one actually depends on this package indirectly in 2024 (not even the author himself), and very few packages ever depended on it directly. Micromatch is largely obsolete given the fact that Node has built in globbing support now [1][2]. We have to let some of these NPM memes go.
Ironically, most of the dependencies are actually Rust crates used by swc and turbopack [1][2]. Try running `cargo tree` on either of those crates, it's enlightening to say the least. And of course, Node has a built in file watcher, and even the most popular third party package for file watching (Chokidar) has a single dependency [3].
React and react-dom are peer dependencies (npmgraph lists them but doesn't graph them visually). The actual full installation command is: `npm install next@latest react@latest react-dom@latest`[1]. Even if you include react and react-dom, the dependency graph still looks tolerable to me: https://npmgraph.js.org/?q=next%4014.2.13%2C+react%4018.3.1%...
The Vision Pro uses optical sensors for hand tracking, so if your hands aren't visible to the device it obviously can't track them. Electromyography solves that problem, and I could imagine Apple integrating some variant of this in a future Apple Watch, and just falling back to optical sensors if you don't own one.
Yeah it is surprising because it seems like a relatively obvious solution. The Watch doesn't use electromyography though [1], it looks like it currently uses "the accelerometer, gyroscope, and optical heart sensor with a new machine learning algorithm." I wonder how accurate that is compared to the EMG solution Meta is using.
Using a list combined with the walrus operator is a clever hack, but it's nice to not be limited to expressions. In JS you can define the equivalent of a multi-line lambda function with any number of statements (which is helpful when you're passing a function as a callback e.g. in a React hook).
It may be nice in the moment, but there's usually regret a few weeks/months down the line when trying to read that code, or angst for the next developer. There isn't that much more effort to just create a normal def to hold that increase in complexity suggested by the need for multiple statements. That's why functions were invented in the first place.
If a callback function gets really unwieldy then you should probably extract it from the call site and define it elsewhere, but that should happen because you decided to, not because the language's limitations coerced you into doing it. The lambda restrictions in Python are probably due to the complexities of parsing indentation based languages, and the clean code argument is just a helpful rationalization. I've never woken up in angst over the fact that I wrote a callback function with two statements in it.
From the blog post you linked: "But the complexity of any proposed solution for this puzzle is immense, to me: it requires the parser (or more precisely, the lexer) to be able to switch back and forth between indent-sensitive and indent-insensitive modes, keeping a stack of previous modes and indentation level."
He's saying exactly what I said: that parsing (or more precisely lexing) makes the problem complex, because Python uses indentation semantically. He then rationalizes avoiding the implementation complexity with a gut feeling: "But none of that takes away my gut feeling".
You see it as a rationalization, while I see it as good sense. After all he also mentioned the "puzzles solvers" who solved the "puzzle", and some would likely have happily provided an implementation if he had given the go-ahead. But he outright refused specifically because "... a user interface can handle only so much complexity or it becomes unusable". You don't need to try putting words in his mouth after he specifically stated that maintaining a simple user interface is higher priority.
And the really ironic thing is that we wouldn't even be having this discussion now if not for this focus, because Python wouldn't have gained such popularity to the point it's also attracting more folk who would destroy what makes it so popular in the first place.
> You don't need to try putting words in his mouth after he specifically stated that maintaining a simple user interface is higher priority.
I'm not trying to put words in his mouth (I'm pretty sure I delineated his direct quotes with quotation marks). But I saw him write multiple paragraphs about the complexity of lexing multi-statement lambdas in Python due to its whitespace sensitivity, and then conclude that the user facing interface must necessarily be complex too, which just feels fallacious to me. If the complexity of the implementation doesn't factor into the design then why go through so much effort to communicate how difficult it is to lex? He compares the implementation to a "2000 step [...] infinite-dimensional" mathematical proof.
I just fundamentally don't buy the argument that one statement in a lambda is fine, but two is dark magic that needs to be removed from the call site and quarantined in a separate def, and I think if the implementation were simpler GVR wouldn't have been so diametrically opposed to the feature. Even if he outsourced the "puzzle solving" to an external contributor, no one enjoys the increased maintenance burden of a complex implementation.
Anyone who's ever written customer facing code knows what it's like to receive a seemingly simple feature request that's actually difficult to implement because of prior architectural decisions, and the "gut reaction" is to convince the user that the feature itself is bad. I hate to invoke comedy but this reminds me of the microservices meme: https://www.youtube.com/watch?v=y8OnoxKotPQ
Maybe it seems fallacious because you've removed it from clarifying context. Keep in mind that he's also against any other form of statement grouping, and so I can definitely see where ambiguity could easily arise in nesting groups of statements. You should also note the "2 or 2000..." statement is just a jab toward mathematicians.
Bit of correction: no statements and a single - arbitrarily complex - expression. An expression can be naturally delineated by parentheses; a statement stands on its own. End of the day, support for statements in a lambda would lead to a need for new symbols. Yet another thing that the user has to learn and remember, whether they're a professional software developer using the language regularly or a biology student using it for part of a one-off project. Again, the outcome of those decisions is clear today, given the general standing of the language.
> "2 or 2000..." statement is just a jab toward mathematicians.
It's a jab towards mathematicians in the context of criticizing a language proposal. He's comparing the complexity of mathematicians and their 2000 line proofs to the complexity of allowing statements in lambdas. He explicitly calls the proposal a "Rube Goldberg contraption".
> Bit of correction: no statements and a single - arbitrarily complex - expression.
I phrased it as a dichotomy between single and multiple statements because in many languages there's the concept of an 'ExpressionStatement', which is a single expression that acts as a statement. This makes the boundaries between a single statement and an expression somewhat murky. In JS for example the MDN docs have this to say about ExpressionStatements: "Apart from the dedicated statement syntaxes, you can also use almost any expression as a statement on its own." [1] GVR himself calls it "the problem of the multi-statement lambda" rather than "the problem of the statement lambda".
I don't want to get bogged down in pedantic debates about terminology though. I completely understand how it works, and said in my very first reply to you: "but it's nice to not be limited to expressions".
> End of the day, support for statements in a lambda would lead to a need for new symbols.
All it would require is a newline character. He calls this out in the blog post: "If the double colon is unpythonic, perhaps a solution could be found that uses a single colon and is still backwards compatible [...] I actually have one in mind: if there's text after the colon, it's a backwards-compatible expression lambda; if there's a newline, it's a multi-line lambda; the rest of the proposal can remain unchanged. Presto, QED, voila, etcetera."
There's absolutely nothing complex about allowing statements in lambdas from a user interface perspective (all of the complexity is in the implementation). Almost every modern language has support for this feature. Even Golang, which is perhaps the epitome of simplicity — the language that fought tooth and nail against generics, and doesn't have a ternary operator (or inline if), or string interpolation — supports defining inline callback functions with statements. There are even whitespace sensitive languages like CoffeeScript that bit the bullet and don't impose any restrictions on lambdas. The simplicity argument just feels really weak to me. At the time that blog post was written a Python user couldn't add a print statement to a lambda to debug their code. How in the world is that simple for biology students and people writing one-off projects?
I also disliked unqualified imports. I can never get used to languages where you can 'import foo' or 'use foo' and it just dumps a bunch of symbols into the current scope. That combined with Swift's 'implicit member expressions' makes it difficult to read code outside of an IDE (although I understand why they made that tradeoff given some of the long identifiers Swift inherited) [1].