Recursion is a powerful, relatively low-level approach, and the price for expressive power is readability, but it has legit use cases. What you said has a grain of truth in that usually you should prefer combinators like map or filter (if you're doing FP), but just throwing away recursion is silly. Having a strong opinion on it and not seeming to know about TCO is also not a good look.
HN user
slikts
[ my public key: https://keybase.io/slikts; my proof: https://keybase.io/slikts/sigs/Yg7YirrQaVsun4cTHhrCUvT5OShLMjuGvHFudwLY8qE ]
Verifying my Blockstack ID is secured with the address 1GypFJtCV2dG5kH8JWuCNNxE6ENLpRcEVu https://explorer.blockstack.org/address/1GypFJtCV2dG5kH8JWuCNNxE6ENLpRcEVu
Without modules there can be dependency hell: conflicting subdependency versions, unless all your dependencies update their subdependencies in lockstep.
You mean statically, not strongly typed. Strong typing roughly means avoiding implicit type coercion.
This is a common straw man; PHP 5 and 7 made large strides, but that's because there was so much to fix, and there still is and will continue to be, like lack of first class functions, actual modules, etc. PHP is also unsuitable for persistent processes like serving WebSocket.
Never, since PHP is fundamentally flawed, and trying to redesign it would make the split between Python 2 and 3 pale in comparison. PHP's main selling point is backwards compatibility and the existing ecosystem; a fundamental redesign would remove that. PHP's name is also mud when it comes to programming language design, and its community is notorious for poor practices, so no one's really clamoring for a more modern PHP.
The bitter truth for PHP stans is that it is what it is, you can get things done, and you can have valid reasons for using it (like legacy reasons, job market, etc.), but it's rightfully trending down and will continue to.
I'll rework that section; thanks for the feedback.
"Very slightly" means that I shared that I'd submitted it here; realistically a couple of upvotes could have come from that, but I don't know. The talk about botnets and whatnot is just hyperbole. You inferring alternative accounts and pulling numbers out of thin air is ridiculous.
The wording is indeed pretentious, hopefully improved in future iterations.
It's a major recurring theme; for example, anything that refers to implicit or explicit is part of it. The list you quoted is a placeholder to be elaborated.
Asynchronicity is just how sequential models are extended to support concurrency. Parallelism and concurrency are orthogonal, so a concurrent model can be executed in parallel.
That looks nice, but Python is an odd choice for studying synchronization primitives considering it has the GIL.
You're right, I qualified it with "classic JVM threads", but a less ancient example would be better; it's just not immediately clear which green thread implementations are also relatively heavyweight like JVM green threads used to be.
That's some fevered imagination.
The trade-offs of locks are accidental locking like deadlocks; message passing removes this trade-off but is less flexible, and dataflow further constrains the use of explicit synchronization. It's part of the larger argument for declarative approaches enabling equational reasoning.
Task/data parallelism bear to be mentioned because they're common terms; thanks for pointing it out.
Thanks, and yeah, the part about lightweight threads stands to be expanded. Other missing parts are reactive vs interactive, linearizable vs serializable and push vs pull.
The relations could definitely be made more clear, but if you could point out what specific terms you find unrelated, I could explain how they fit together. The basic organization is working up the ladder of abstraction; for example, scheduling is a fundamental concept, so it comes before other concepts that rely on it (which is all of them).
For what it's worth, the feedback I've had so far elsewhere suggests that there aren't particular inaccuracies. A somewhat contentious part is defining concurrency in terms of order independence, but the main source for that is Peter Van Roy (https://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf section 4.3), so it's of good provenance.
The implicit coercion rules don't matter if you make sure to convert the types explicitly, but then you're just relying on your discipline. You might be able to pull it off individually, but it starts mattering more when working with other people.
Also, from a brief glance at your code example, you don't seem to have caught up with other current best practices like linting or modules.
You can't remove JavaScript features without breaking websites. The one exception was when the strict mode pragma was added, but that was a one-off, and there's too much resistance now to add more pragmas (they tried that with "strong mode").
The best solution currently is to have linter rules enforcing ===.
The issue there is that TS allows dropping out of the type system with `any`, so it might not actually be checking the types you're comparing, so I'd still use ===.
It's idiomatic to use == to check for both null and undefined at least.
A lot of people seem to have a perception of languages as being handed down by some language gods, and apparent problems with the language get explained away by "mere users" lacking knowledge, perspective, discipline, etc.
Odd to post something you haven't made as "Show HN".
Yet you don't mention an alternative explanation.
You jump to arguing legality, but morality comes before that, or should anyway, particularly because it's a company vs an individual.
Are you going to add this disclaimer to everything you do now, or is the idea to just take the name over with your capital? It's their name that they've established by being a prolific, well-respected developer; it was also the only search result for it before you appeared, because it's a unique name without an another established meaning. There's no explanation for why you'd choose it outside of not doing due dilligence or just lack of morals.
Or is it that you googled and decided you can just take over someone's identity because they haven't registered a .com. It's not like "substack" would be a thing outside of it.
So you couldn't be bothered to google for the name? It's not just their Twitter handle; they've published some of the most popular npm packages of all time under it; there's who knows how many millions of users.
I have trouble picturing what advantage that setup would give over using ESM or node modules.
The Function constructor is a better alternative for eval(), but still only as a last resort. eval() itself has no use cases.
I find that most JS criticism is ill-informed, because people are too quick to jump to blaming the language due to its reputation. Not that I'd call JS a great language, but it has redeeming aspects.
eval() has no legit use case in JS, and I really don't understand what the point of "// @export" would be. You can't reflect on module or function scopes, but that's a feature and gives you encapsulation.
for-in is a legacy feature; due to dynamic inheritance, it's generally not safe to use without also calling Object#hasOwnProperty() every iteration. for-of is not for "array elems", it uses the iteration protocols that are implemented for all built-in collection types, not just Array, and some DOM types, and can be implemented for any user types. Protocols are a much more flexible and clean approach to metaprogramming than overloading the for-in looping construct would be.
You can't use Proxy if you need to target legacy browsers like IE9, and Vue needs to, since it's about 15% of all browsers.
Dynamic imports don't replace static imports.