Hacker News new | past | comments | ask | show | jobs | submit | kflgkans's comments login

You're mistaken. This is no joke.

Was it your intention that the dancing stick figure gives people nightmares?

stick is life

Last I checked WASM applications are single threaded, not sure if that's changed. GC is concurrent, but not parallelized.


Zig is a completely different language than Rust. Memory safety is just one aspect. I personally find Rust to be very difficult to read and can never manage to be productive in it.


Lacking memory safety is a fundamental mistake in my opinion, not merely one aspect. We have learned much from the days of C and C++, so much that companies are migrating away and finding that many of their bugs are solved with memory safe languages like Rust.


I forgot to follow up on this, I don't know how to make HN give me some kind of a notification on replies to my comments.

I should have been a bit more clear. I love memory safety. But I dislike a lot of other aspects specific to Rust. I would much prefer e.g. C with memory safety (somehow). So that is, for me, why not Rust. Rust is more more than just memory safety.


https://www.hnreplies.com is an unofficial way to get comment replies via email.

Perhaps you should look into Vale or Pony then, they have memory safety like Rust, also without a GC, but they use different mechanisms for it.


> I don't know how to make HN give me some kind of a notification on replies to my comments

I built https://hackernewsalerts.com for that


The most common pattern in languages with explicit error handling, is to simply return the error (possibly with some context added) in every function up to the point where the process was started (e.g. an HTTP endpoint handler, or the CLI's main function) to deal with it.

I'm not saying exceptions are good, but I am saying that they do represent the most common error handling pattern.


Right, this is largely the same idea. For things that have to be bubbled up, you wind up in the simplistic "single thread of execution by an operator" pattern. And, in that scenario, exceptions work exactly the same as just returning it all the way up. It is literally just making it easier to unwind the stack.

My assertion is that actual error handling in workflows doesn't work in that manner. Automated workflows have to either be able to work with the value where it was broken, or generally just mark the entire workflow as busted. In that scenario, you don't bubble up the exception, you instead bubble up an error code stating why it failed so that that can be recorded for later consideration. Along the way of bubbling up, you may take alternative actions.


Thanks for the additional clarification!


Certainly! And please let me know if I'm off or otherwise confused here. I can guarantee I'm not the brightest bulb around here! :D


If there is anyone here who has time to explain to me (or link articles about) why functional components and hooks are considered to be better than class components, please enlighten me.

Up until roughly 4-5 years ago I was doing small front-end React apps on the side (I'm a backend engineer) and was feeling very productive with class components. They made sense to me, concerns were nicely separated, and I felt I could reason pretty well about what was called when and how state was manipulated.

Then hooks came around, I tried them a few times, but I just felt so lost. Suddenly everything is intermingled in one function and we're using side effects to react to changes and manipulate state. I could no longer understand when which code was executed, and especially following and manipulating state became impossible for me.

The projects I already, I kept with class components. Haven't done any new front-end projects since then.


React's mental model has always been UI = F(data) and in ideal case any component is a pure function. But, of course, in most real apps there are cases when this mental model breaks: internal state, animations and side effects. The old way to provide escape hatches for those cases was to wrap a function into a class, where original function is 'render' method and the cases above are handled with lifecycle methods. The problem was that one piece of functionality often required updating several lifecycle methods, and for a big component that non-locality made things very hard. Hooks are a different way to express non-purity that keep code more local.


Thanks, that makes sense. Interesting perspective on the UI = F(data), I did not know that. I still wish the mechanics were a bit more... intuitive... I guess? Personally, I'm a big fan of The Elm Architecture [1]. I felt that is a very nice way to separate state and logic. But I'm not such a big fan of Elm itself (subjectively).

[1] https://guide.elm-lang.org/architecture/


There was a great interview on ACM Queue [0] where they explain that paradigm. As a rule of thumb. Try to keep everything functional, and if you want to have state, keep it contained to its component.

[0]: https://dl.acm.org/doi/10.1145/2984629.2994373


I only knew React until my current job, which uses Vue. I'd strongly recommend trying a framework other than React for your next project. After you're past the learning curve, it's much more intuitive.


> I'd strongly recommend trying a framework other than React for your next project.

This gave me a good chuckle (if you read it as next.js)


I've tried many of them. They all suck.


Not a crazy take.

Then try something like snabbdom or mithril.js.


I'm glad I'm not alone in that sentiment. I haven't touched react since the move to hooks. People seem to like them though?


No, not really. Some do, some don't. There are valid criticisms to dislike them. I'm on the side that thinks they are bad.


> If there is anyone here who has time to explain to me (or link articles about) why functional components and hooks are considered to be better than class components, please enlighten me.

Static evaluation of which instance properties are being used in a class instance is much harder than evaluating which variables are being referenced in a function. There's no need to worry about calling context or binding instance methods. Functions minify much better because you don't have to worry about preserving long property names like componentDidUpdate. With class components, sharing logic involving state between components required either functions taking a state setter and whatever slice of state you needed, or--more commonly--higher order components. With function components and hooks, the code responsible for initializing and updating state isn't tied to an instance. Now you can share that code with a plain function without needing to pass an entire slice of state and an update function into it. Instead of needing to shove all your update-related code into the same componentDidUpdate or componentWillUnmount methods, you now split them into different calls to useEffect.

> Suddenly everything is intermingled in one function and we're using side effects to react to changes and manipulate state. I could no longer understand when which code was executed, and especially following and manipulating state became impossible for me.

If you're talking about using useEffect to respond to changes by setting state: that's almost always a code smell and sounds like trying to sync state with props. This was an anti-pattern long before hooks, and was called out explicitly in the docs.

Having worked on a lot of class components and function components, class components offer a lot more opportunities for bugs which can't be statically prevented. On the other hand, most of these bugs can be caught in function components and hooks by a linter, or are just prevented entirely by the design. A frequent question which came up during the class component era was what code belonged in the class's constructor, componentWillMount, or componentDidMount methods. This always came with caveats, because generally component initialization isn't something developers should be thinking about because it can happen many times before anything appears on screen. Function components offer fewer opportunities for this. The useEffect hook forces people to think purely in terms of running effects in response to changes in variables which have been closed over, and about what things need to be done to clean up after the effect has run. Responding to user events (e.g. onClick) is almost exactly the same as it's always been other than cosmetic changes.

I'm not sure how everything being in a single function offers worse organization than everything being within a class. Instead of instance properties you have variables. Instead of methods you have inner functions.


I like explicit over implicit. I will take passing down context (in the sense of the concept, not the specific Go implementation) explicitly everywhere over implicit ("put it somewhere and I'll trust I can [probably, hopefully] get it back later") any day of the week.

I've seen plenty of issues in Java codebases where there was an assumption some item was in the Thread Local storage (e.g. to add some context to a log statement or metric) and it just wasn't there (mostly because code switched to a different thread, sometimes due to a "refactor" where stuff was renamed in one place but not in another).


Most recently ive been bit by this with datadog. The Python version does some monkeypatching to inject trace info. The go version you need to inject the trace info explicitly. While the latter takes more setup, it was much easier to understand what was going on and to debug when we ran into issues.


Sounds very familiar. I was a Java developer for a long time, and in that ecosystem adding a library to your project can be enough for code to be activated and run. There are plenty of libraries where the idea is: just include it, magic stuff will happen, and everything works! That is, until it doesn't work. And then you have to try and debug all this magic stuff of how Java automatically loads classes, how these classes are created and run, and what they do. Didn't happen very often, but when it happened usually a full week was wasted with this.

I really prefer spending a bit more time to set it up myself (and learn something about what I'm using in the process) and knowing how it works, than all the implicit magic.


This is why I avoid Python. I started doing Go after looking for few solutions written and Python and I couldn’t use it.

Some magic values inside objects of recursive depth changing dynamically at the runtime. After working for some time with functional languages and languages with non-mutable structures I’m afraid of such features today.

Context is nice because it’s explicit. Even function header spills the detail. `GetXFromName(context.Context, string)` already says that this call will do some IO/remote call and might never return or be subject of cancellation.


If it is just a transport mechanism, why use context at all ant not a typed struct?


Because dozens of in between layers don't need to know the type, and should in fact work regardless of the specific type.

Context tells you enough: someone, somewhere may do magic with this if you pass it down the chain.

And in good Go tradition it's explicit about this: functions that don't take a context don't (generally) do that kind of magic.

If anything it mixes two concerns: cancelation and dynamic scoping.

But I'm not sure having two different parameters would be better.


I think it's simply survivorship bias. Thousands of people try this and fail. And occasionally you read an article like this, which is like the one in a million who managed to get lucky with their ideas and manage to make it a success. And I think they underestimate how much luck they had.


Luck is a huge factor for sure but I also think it's not as hard as you're making it out to be if you set yourself up for success.

I have four products that make money, built over the course of seven years. None of them really benefit from each other. If it was pure luck and 1/1,000 chance of success I don't think my current portfolio would be possible. (I also have a lot of failures, so I agree there's luck and risk, just not as strong as you're making it out to be)


Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: