1. 67

    I think this is both a sensible and a delightful idea.

    1. 11

      (the immediately following line is written to display contrast with the parent post while retaining structure, not to be mean to the parent or to endorse suggest a particular approach)

      I think it’s neither sensible nor a delightful idea. ;)

      It helps to elaborate more, and none of the 41 people that evidently agree with you seem to be posting beneath you to expand on the point. :(

      Actual opinion follows:

      I’m in support of civil and kind communities (see writeup on the friendlysock experiment ). All of us should always have useful discussion, and when we invariably disagree we should always do so politely and without attacking the person with whom we share a difference of opinion. It’s okay to speak ill of an idea, it’s almost never okay to do the same of a person.

      That said, time and time again things like troll or other flags tend to get used to bludgeon other users outside of their initial purpose. I’m not sure if there’s a good solution to that, and in the meantime would propose that we tolerate a little bit of off-topic discussion when it comes up in the form of gentle reminders for folks to stay polite and be more charitable in their posting.

      1. 23

        If we want to fix the fundamental problems with irate comment sections everywhere, we need to make kindness a first class notion and optimize for it.

        1. 9

          Sensible: asking people not to be unkind avoids the downward spiral of negativity ruining threads, and eventually, the whole community. A ban on unkindness is not a requirement to be kind, you can be neural. It’s not hard to spot unkindness, it’s mostly obvious and unambiguous.

          Delightful: most platforms are net negatives in peoples’ lives because of unkindness. It’s a delightful idea to create a tool which lets this community be different.

          HN is a community that allows unkindness, and it is the worse for it. This is a change that would improve Lobsters by making it even less like HN.

          1. 11

            While the friendlysock experiment is much appreciated, your posts are still often frustrating for me to read due to their unnecessarily discouraging nature. There remains work to be done. Would you like to know when your posts are not as effective as they could be? It’s a lot of energy to provide this kind of feedback, and you usually won’t get any unless it’s over the top offensive.

            You’re probably wondering “what have I said that sounded unkind?” but I don’t have time or emotional energy to do the digging, but that information would already exist for you if this tag existed. I know you want to improve, and this tag would help you.

            1. 3

              I also feel this way about @friendlysock’s comments. They consistently have a neutral-to-negative affect and are rarely substantive in the way that friendlysock seems assured that they are. I don’t know if the friendlysock “experiment” is ongoing, but that post does not match my experience of the author’s online presence. But I never comment because 1) it doesn’t seem worth it and 2) friendlysock himself tends to call these digressions off-topic. It would be great if there was a way to hide users in the way that one can hide submissions.

              1. 2

                Would you like to know when your posts are not as effective as they could be?

                I’d like an explanation more than a flag, certainly! :)

                1. 5

                  Sure, but that’s a rather expensive act of charity, and over time I just learn to use this site less instead of donating energy to help someone optimize their communication.

                  As you get feedback when you cross a boundary, you learn to avoid that boundary. For this reason, we must be judicious in our choice of the boundaries which yield information that we can learn from in desired ways. The current boundary for feedback is quite a bit above the threshold where I feel like I’m worse off for having read a comment. This is subjective, but the weighted response of this thread seems to indicate that I might not be in the minority here.

                  I am quite appreciative that you are interested in applying this information. But it ain’t cheap to give out.

                  1. 2

                    It’s not an act of charity so much as the cost for having a well-functioning community.

                    If we value the quality of discourse and discussion, it makes sense that we might from time to time have to give back in the form of polite guidance. Flagging without explanation only muddles the feedback required to promote good behavior.

                    Thank you for your comment, since it helped me figure out how to articulate something. :)

              2. 5

                I like the take from the orange site’s guidelines:

                When disagreeing, please reply to the argument instead of calling names. “That is idiotic; 1 + 1 is 2, not 3” can be shortened to “1 + 1 is 2, not 3.”

                1. 7

                  troll was used as a general “i disagree with you but i can’t/won’t say why”.

                  At the end of the day, if people are not willing to entertain different thoughts, challenge their own world view and preconception and strive for internal consistency, then they won’t. No amount of clever setup will change that.

                  People use the downvote system the same way they use the comment system. They decide what they are going to do (disagree/downvote) and then they reach for the closest way to do that (rationalisation/call ‘troll’). You can’t change people that do not want to change.

                  But if you want my ‘clever’ way, simply make everybody write a 30 words explanation of why they are downvoting. Then you list the explanations on every post.

                  1. 3

                    troll was used as a general “i disagree with you but i can’t/won’t say why”.

                    Yup that’s my biggest issue. I don’t mind being labeled a troll if I’m trolling, but I’ve seen it used a LOT when the reaction was actually more like HOLY CRAP YOU ARE SO WRONG which is not its intended purpose IMO.

                    1. 3

                      Note that my post higher in this is currently marked with +2 incorrect (with no clear explanation of how it’s incorrect) and +1 troll (despite it being neither troll nor its trollishness being explained).

                      Like, in this very thread, we see how we folks are likely to misuse yet another option.

                      1. 1

                        That’s an excellent point. I think many of us were responding because we like the idea without actually considering how effective the implementation would be.

                      2. 2

                        I’ve used “troll” on a few occasions where someone is just not engaging in what I consider to be a constructive discourse, mostly when a significant part of their reply consists of a logical fallacy (e.g. red herrings, moving the goal posts, etc.)

                        I guess this could be phrased as “HOLY CRAP YOU ARE SO WRONG”, but in my experience people using a lot of logical fallacies are generally not interested in constructive debate, merely “proving” their pre-conceived notions about something, which could be considered “trolling”, kind of.

                        1. 1

                          I guess this could be phrased as “HOLY CRAP YOU ARE SO WRONG”, but in my experience people using a lot of logical fallacies are generally not interested in constructive debate, merely “proving” their pre-conceived notions about something, which could be considered “trolling”, kind of.

                          That seems like a fairly big assumption on your part, does it not? You’re ascribing both motive and expected future behavior to someone based on essentially being wrong.

                          Rather than marking them troll, why not take the opportunity to let them know they’re using fallacious arguments?

                          I get it if you’ve done this and they persist, but off the bat? Not so much.

                          Brass tacks: I can see wanting to downvote such behavior, but are they actually being a troll?

                          1. 2

                            Note I don’t do it “off the bat”, but if you just keep replying for the sake of it then you’ve clearly stopped caring about constructive discourse and just want to “win” and/or have the last word. That’s not just “being incorrect”, I think.
                            It’s fine to be incorrect, I generally don’t even bother to downvote it, but it’s another to reply with silly come-back “zingers” to score “argument points” to “win” the argument.

                            Essentially, if a reply makes me go “ahh, come on man, that’s just lame” then it’s beyond being just “incorrect”. “Troll” is a very nebulous concept, but I like the broad concept of “needless arguing”. I don’t really care about their motivations, the end result is the same.

                            Rather than marking them troll, why not take the opportunity to let them know they’re using fallacious arguments?

                            Because it’s time-consuming, frequently not effective, and I have other things I want to do with my life.

                            1. 2

                              Because it’s time-consuming, frequently not effective, and I have other things I want to do with my life.

                              Then - just my $.02 please feel free to disregard, but consider simply walking away rather than (in my opinion) misusing a flag?

                    2. 1

                      I don’t think it should be ‘worth’ a full point of downvote, but I’m not sure if differing penalties depending on downvote reason is implemented.

                  1. 34

                    I’m very strongly in favour of objective, civil, polite discourse. I don’t think anything is gained by penalising people if their tone is a little abrasive.

                    To be blunt (in full acceptance of the irony here) I would much rather that people post abrasive content than risk them self-censoring for fear of appearing “unkind”. I’m afraid that lobste.rs would cease being a haven for constructive discussion, and become some sort of Stepford-esque echo chamber instead.

                    1. 46

                      You can disagree with something without being a jerk about it. I think that’s something we should all aspire to.

                      1. 11

                        I agree (and think that “being a jerk” is quite a different thing to “being abrasive”, but maybe that’s just my reading of the terms).

                        However, I’ll take “abrasive and correct” over “nice but wrong” any day of the week, and I fear that encouraging downvotes over tone will result in the loss of some of the former.

                        1. 7

                          I’ll take “abrasive and correct” over “nice but wrong” any day of the week, and I fear that encouraging downvotes over tone will result in the loss of some of the former.

                          Fortunately, these are not the only two options. An ideal solution would discourage the “abrasive and correct” in favor of the “non-abrasive and correct.” In such an environment, “nice and wrong” comments are welcome because they spark informative discussions.

                          1. 2

                            Which is why a downvote, as they’re currently implemented, isn’t a good solution. Some sort of separate flag might be, though. Provide an easy way for readers to nudge posters to edit their posts for tone.

                            1. 1

                              “Nice and wrong” comments that require other people to expend effort to correct them are not kind.

                              1. 6

                                The “incorrect” flag covers those, however.

                            2. 4

                              Perhaps the “unkind” vote should have zero affect on karma, but still deprioritize the comment? That way it’s less likely to generate feelings of defensive?

                              1. 4

                                Being unkind seems very karma-related to me

                                1. 4

                                  It could just be some CSS that provides visual feedback from the downvote action to the voter. Like a big red mechanical button that isn’t wired up to anything, but feels satisfying to press.

                              2. 6

                                You certainly can. But anger and frustration, like other human emotions, have circumstances where they are objectively justified and reasonable. One would say that in software development, for example, we aren’t really facing the questions of life and death, and getting worked up about something like that is silly. I agree that a lot of anger in comment sections is, indeed, silly – but not all of it.

                                Let me bring an example. Recently I found out that one company, which is developing a technology which have been my main “specialisation” since 2012, have decided to move around different modules and in the process deleted documentation for one of it - so from new version on, instead of automatically generated API specification, with all classes and methods, I would have to refer to guides, organised by topic. This change is completely unnecessary, and will make my day-to-day work much harder. I spend 8 hours a day, 5 days a week, at my job, and something that they have done will make me a little bit more miserable, every day. And they don’t even have any reason for it. And a forum post that I’ve written, with detailed explanation of the issue, and then tweeted at them, have gone without a single reply.

                                Now, if I would encounter the person who was responsible for this decision here in the comments in a relevant thread, I think that venting my frustration, while staying civilised, would be an appropriate response. Don’t you?

                                1. 6

                                  And yet, being direct is often seen as being unkind. I’m strongly against ranking people on kindness – in addition to being very vague, the norms are highly cultural.

                                  I sometimes wonder if we’d be better of getting rid of votes entirely, and rely on people using their words.

                                  1. 6

                                    highly cultural

                                    But surely we’re seeking to build a lobste.rs culture?

                                  2. 2

                                    100% agreed. In my experience you’re also more likely to effectively get your argument across. However, it is a skill that requires effort to learn and apply – at least in my case.

                                    1. 1

                                      but you can’t guarantee that people will interpret your politeness as such

                                    2. 38

                                      I would much rather that people post abrasive content than risk them self-censoring for fear of appearing “unkind”. I’m afraid that lobste.rs would cease being a haven for constructive discussion

                                      The opposite is also true: some people stop posting after too many negative interactions, which also reduces participation.

                                      You call it “censorship”. Frankly, I’m starting to strongly dislike this term. It’s carelessly thrown around far too often. Every community has social norms, and online communities are no exception. If I’m an asshole to my friends then at some point they’ll start shunning me. If I join a football club (or scout group, or choir, or whatever) and act like an asshole then sooner or later I’ll be asked not to come next week. Would you call this “censorship”? I wouldn’t.

                                      I stopped posting on /r/programming at reddit after being called a “moron”, “idiot”, “retard”, accused of having an IQ lower than 65, was told that I “fucking suck at making software (and I guess generally anything)”, was told that my opinion was “hates speech” in two separate recent incidents (both over a technical disagreement, wtf?!), and just general unconstructive/aggressive/belittling/etc. word choice.

                                      It’s not that I’m that sensitive, but if you spend a lot of time writing a weblog post, or make some software, and you get told any of the above (which are all real quotes) then that’s … not great. It’s not that I get angry or “offended”, but it’s also not fun and if it happens a few times I’ll stop coming back (as happened on /r/programming). I think most people participate in these communities just for the fun of it. Sure, you also learn new stuff, but I think fun is an important – if not the most important – part for many.

                                      Constructive discussion can only happen if everyone feels like they can participate without the fear of being mistreated (belittling, aggressive replies, insults, etc.) If there is such a fear, then I will guarantee you that some people simply won’t post at all.

                                      I’m not sure (yet) if a flag is a good idea here for other reasons (I’ll make another top-level comment about that), but I do (strongly) disagree with your sentiment.

                                      1. 18

                                        I definitely use this site less over time because of the loud frequent posters who often carelessly put down people with insensitive wording. When I was junior I was able to justify spending the emotional energy listening to technically correct jerks, but nowadays it’s pretty rare that I get anything other than anger out of their childish communication. I only come on lobste.rs now when I’ve got pretty high emotional buffers, because otherwise it’s likely to just make me feel worse.

                                        1. 7

                                          I’ve only been here for a few months, so I can’t comment on Lobste.rs specifically, but I can comment on two general observations:

                                          • Often >90% of the problems come from ~1% of the people.
                                          • As a community becomes larger, it becomes harder to manage because mods don’t see most of what’s going on (making it harder to identify patterns).

                                          In many ways it’s the same as traffic; if you drive or cycle home you may encounter 100 drivers, so if just 1% is reckless driver then you’ll meet one most days. Also, like traffic, it’s hard to completely remove these people unless they commit gross offences. You can break traffic laws and be reckless for pretty much your entire life, and suffer very few consequences.

                                          Most of us act like an asshole sometimes; I know I do; I have pretty strong feelings about certain political topics, and sometimes I just have a bad day. But I’m not consistently an asshole. I think they key here is not to look at individual comments too much, but rather at long-standing patterns. There are just a few mods here, and they probably don’t see most of what’s going on. So the ability to see things like “hey, this user is responsible for 28% of all unkind flags” is the critical bit.

                                          I don’t know if this needs to be tied to downvoting. Could just be a separate flag. I don’t think it matters too much, as long as there’s an admin panel to see an overview.

                                        2. 6

                                          This is exactly what happened to Slashdot too. The loudest, most aggressive users gradually took over the comment section, and the more rational voices left. That site is now a quagmire of hate speech. I think it is a good idea to get ahead of it on this site, because it could happen here too. I like the discussion environment of this site, and I don’t want to lose yet another community.

                                          I think that the idea of shadowbanning from reddit could be combined with the stack overflow style of flagging bad behavior. If nobody can see abusive or trollish comments, then they don’t accumulate comments and effectively don’t exist (i.e., not rewarding bad behavior). Those users will either correct their behavior or stop posting altogether.

                                          1. 3

                                            I’m sorry you experienced that behaviour. I have myself, largely for holding unpopular political opinions[1] . It’s even more fun when people attack those positions in a social situation, before realising that someone in the group actually holds them :)

                                            The behaviour you describe crosses way beyond “abrasive” to downright abusive. I’d be okay with a flat out ban in the case of someone who called another poster a retard, for example.

                                            By “abrasive” I mean posts that might be terse, strongly critical, or dismissive. That is, posts that have issues with tone. Things that could be charitably interpreted as well intentioned.

                                            [1] I guess you’d call them Objectivist, for want of a better term. Strongly socially and economically liberal. The former is common in Australian tech circles, the latter rare. People here usually assume party-political alignment, so if you’re say in favour of open immigration, they assume you’re also in favour of progressive taxation.

                                            1. 1

                                              The reddit example is of course much more extreme than anything I’ve seen here; but it does clearly illustrate the point that people can stop posting (“self-censor”) due to lack of moderation, too.

                                              By “abrasive” I mean posts that might be terse, strongly critical, or dismissive. That is, posts that have issues with tone. Things that could be charitably interpreted as well intentioned.

                                              A good rule-of-thumb is whether a comment makes you go sigh, “eh”, “pff”, or something similar, either by actually saying it or saying it “in your head”. You can be critical of what someone said and not evoke such a response. My previous comment was critical of your post, but I don’t think if evoked a “pff” response (or at least, I hope it didn’t!) but it’s not hard to imagine that it could with some stuff rephrased.

                                              I know this is murky and unclear, but that’s the way language works, especially in a global community with different cultures, etc.

                                              I think the key thing here is that “abrasiveness” accumulates. If you encounter an abrasive comment on occasion then that’s okay. Most people are abrasive some of the time (I know I am); that’s just the way things work. The problem is when people are abrasive most of the time, and you encounter abrasive everywhere you look.

                                              I don’t think singular abrasive comments are a problem, or that people should be punished for it. But if they’re constantly making them then there is a problem that should be addressed. Also see my other reply in this thread: https://lobste.rs/s/xnjo8g/add_downvote_reason_unkind#c_kqtuqr

                                              Analogy: Lobste.rs keeps track of “self promoters”; people who frequently post links to their own websites. Is this preventing people from submitting links to their own site? Not really; but it does help keep track of people who spam links too frequently. I think a potential “unkind flag” should work the same way.

                                            2. 2

                                              “Censorship” is certainly an overused weasel-word nowadays. Moderation is (generally) not censorship.

                                            3. 9

                                              Just to clarify, this kind of “bluntness” is of course perfectly acceptable. If you’d labeled my suggestion a “crap idea” on the other hand…

                                              1. 4

                                                And that’s the rub, isn’t it? I have no problem with having my ideas called crap, but don’t like calling people “crap”. Others might be more sensitive than you, and then you have a ratchet that moves in only one direction, as people say less, challenge each other less, and so on.

                                              2. 4

                                                Just to piggy-back on this a bit. I wholeheartedly applaud the heart behind this suggestion, I prefer that the tone be kept civil and polite here. However, kind/unkind might be a bit too subjective and might unwittingly stifle conversation. My concern is that for one person, a simple disagreement with an idea could be deemed “unkind” regardless of tone. My skin might be a little thinner, so my unkind trigger finger might be more prone to fire. I think troll covers abrasive behavior and perhaps some kind of flag could be used to alert moderators when issues arise and tone sinks too low in a conversation.

                                              1. 14

                                                I feel hurt when I see other people being punched unnecessarily. It has made me spend less time on this site when I’m not in high spirits. I’m happy to use “troll” in situations where someone is clearly treating someone else like a punching bag, but I would like to be more specific sometimes. I like the idea of flagging something as “unkind” instead, in the hopes that it provides more specific feedback for the commentor. They may not have realized that their words were less effective in conveying their sensible core message than they realized.

                                                We should strive to have cheap mechanisms for helping people who want to improve their communication skills to do so, as well as ranking objectively true yet hurtful content below things that are objectively true without so much toxicity.

                                                1. 8

                                                  ranking objectively true yet hurtful content below things that are objectively true without so much toxicity.

                                                  I’m strongly in favor of this. Some people on this site seem to value correctness above all else when it comes to ranking comments, but for me, kindness and civility are more fundamentally important. It doesn’t matter how true your comment is if it’s also condescending, insulting, dismissive, bigoted, or hateful. I just don’t enjoy reading things like that—even if they aren’t directed at me—and I think that to ignore this dimension in favor of correctness is to forget that this site is a place for people to communicate, and that if you want those people to keep coming back then you must treat them well.

                                                1. 2

                                                  What is the big selling point of this frugality?

                                                  You spent 5-10 years working in an environment where there’s a lot of people and a lot of things happen.

                                                  Then you have saved up enough to move to somewhere that your $25k will last you through a year - but what is the point of being retired, when you have nothing to and need to keep living frugally?

                                                  I’m genuinely curious as to why this would be appealing - I’m guessing I’m overlooking some aspect, can some of you help me to figure out what it is?

                                                  1. 14

                                                    I heard it described best as: retirement isn’t “not working”, it’s “not needing to work”. The appeal is freedom and security. You can do the things that you value most, instead of the things that value you most.

                                                    1. 12

                                                      Spent my 20s working in NYC and SF. Moved to Berlin, cut cost of living to something like $10-12k/yr. It is extremely liberating to not need to work. I spent the first couple years working something like 1-2 months per year, mostly just to convince myself that I could still get a job if I wanted, and the rest of the time doing serious leveling up of various skills, many engineering-related. In those 2 years of mostly not working, I dramatically increased my employability by gaining some fairly rare engineering skillsets that I had always been attracted to but never had the time to really master while holding down a full-time job.

                                                      Now I’m working full-time again, but only because I found a place that is totally aligned with the things I want to bring into the world anyway. I get to run around the world teaching people about Rust, spend time building my database, sled, and spend time doing distributed systems and database work with clients. Being able to easily say no to things that consume your time really increases the chances of you finding better opportunities. I never felt this freedom when I was doing the engineering rat race in the US.

                                                      1. 8

                                                        You can do the things that you value most, instead of the things that value you most.

                                                        As long as they fit within your budget of $XXk/yr. It’s one thing to be a 20-something living with roommates on $25k/yr but don’t bother getting married or having kids and expect to keep to that budget. Most of these “retire by 30” advocates are hopelessly naive on this point.

                                                        1. 3

                                                          But $25k/yr is the medium post-tax income in one of the richest countries in the world. Can half of working Americans not afford to get married or have kids?

                                                          1. 3

                                                            It depends on what you mean by “afford”. Consider the costs of childcare, the fact that the poverty line for a family of four is (slightly) over $25k/year[1], and that without an employer you’ll be responsible for your own medical bills/insurance (unless medicaid-eligible). Consider also that the per capita personal debt in the U.S. is $38k – i.e. 1.5x the median annual income.

                                                            [1] https://aspe.hhs.gov/2019-poverty-guidelines

                                                            1. 3

                                                              If your partner is in the same situation then you’re looking at 50k / year. But, yeah, if only one parent works or if you’re a single parent then 25k might be difficult.

                                                              At least you don’t need to pay for childcare though if you’re not away at work all the time.

                                                            2. 3

                                                              Harsh reality for those who think we are a rich country. Averages lie.

                                                              https://money.cnn.com/2018/05/22/pf/emergency-expenses-household-finances/index.html

                                                              We are a nation of poor people with a rich 1%.

                                                          2. 4

                                                            You can do the things that you value most, instead of the things that value you most.

                                                            This is a wonderful phrasing. Did you come up with it?

                                                            1. 11

                                                              Yes but it was before having coffee, so if you like it then it’s entirely accidental. :-p

                                                          3. 7

                                                            Frugality is relative - living on the US median income doesn’t require a huge amount of sacrifice. “Somewhere that your $25k will last you through a year” is the majority of places in the world. Half of the US (and 99% of the world) earns less, and doesn’t have the additional benefit of a big pile of cash for emergencies.

                                                            A framing I found useful but didn’t include in the article is: imagine you live the median lifestyle and you can now afford to retire. Do you want to work another 20-30 years to pay for additional luxuries? The answer might still be yes for many people, but I think its really valuable either way to explicitly consider the question.

                                                            Personally I found that a lot of my spending was on things I didn’t really care about much, so I was able to spend a lot less with a little forward planning. Perhaps a better way to convey the idea is ‘spending money efficiently’ - applying some attention to checking that you are getting a good conversion rate from time spent to happiness gained.

                                                            And, as soemone else touched on already, even if you want to work and have a more expensive lifestyle, its really valuable to know that you could survive being unemployed for a long time. Rather than having to work, you are choosing to work. If conditions change, eg your employer screws you around, you can safely vote with your feet.

                                                            1. 5

                                                              I don’t necessarily agree with this framing, but it’s right there in the article:

                                                              By separating the means of earning money from the freedom you are pursuing, it enables pursuing goals in that under-served intersection of valuable but not profitable. Whether that’s supporting free software, producing art or home-schooling your children,

                                                              FWIW your comment didn’t come off as well-intentioned… it seems sarcastic. Something like “I wouldn’t want to be retired” or “Retired people have the problem of finding something to do” would have made the same point.

                                                              1. 2

                                                                Appreciate the feedback on my comment - I’ll keep it in mind.

                                                              2. 5

                                                                What is the big selling point of this frugality?

                                                                In the context of this article, the author seems to be deliberately conflating (or at least comparing) startup funding and expenses with personal finances and retirement. The argument is that when you run a business, if you have your cash reserves in some interest-bearing investment and then keep your expenses low, you get more than what you saved in the end. Which is basically just another illustration of the magic of compound interest.

                                                                The big selling point of early retirement, for me, is freedom. I don’t have the entrepreneur mindset or the required skills. I could learn them, and be okay at it if I really had to, but that’s not where my interests lie. I want to wake up in the morning and do the first thing that comes to mind, even if it’s not something that can (directly) make me money. I can’t do that right now while my life situation demands a steady paycheck.

                                                                You spent 5-10 years working in an environment where there’s a lot of people and a lot of things happen.

                                                                Then you have saved up enough to move to somewhere that your $25k will last you through a year - but what is the point of being retired, when you have nothing to and need to keep living frugally?

                                                                The word “retired” in reference to early retirement is often both used wrong and misunderstood. A better phase would be “financially independent,” although that still carries some baggage as it was historically used to refer to the wealthy. Certainly, the wealthy are (or can be) financially independent but frugality enables the middle class to be financially independent without being wealthy.

                                                                People with the goal of retiring early aren’t (usually) looking to pack it all up and live out the remainder of their lives aimlessly and without purpose. The goal is get to a place where work is optional and they have the ability to pick and choose what they take on and spend more time with the people they care about the most. Early retirees typically think of it as retiring to something rather than retiring from something.

                                                                There are people who are genuinely happy with their jobs and are content to work full-time until age 65 or later. And that’s perfectly okay if that’s what they really want. It’s just that a lot us are starting to realize that with the right planning, this doesn’t have to be the only way through life, as our culture has taught us.

                                                                Finally, be careful not to confuse frugality with deprivation. Frugality is simply being analytical and mindful about how you spend and manage your money. It’s learning that spending money on novelties and temporary experiences does not actually make you any happier in the long term, despite what western pop culture (which is driven largely by advertising and marketing) has ingrained in us.

                                                                1. 4

                                                                  the author seems to be deliberately conflating (or at least comparing) startup funding and expenses with personal finances and retirement.

                                                                  Not startup funding, but startups vs fire as strategies for having lots of autonomy. I know a lot of people for whom a big part of the appeal of the startup world is having lots of control over what they do and how they do it. But financial independence can do that too, and is more attainable than many people realize. The compromises are different - even more freedom at the expense of lower income.

                                                                  But otherwise I agree with everything you said.

                                                                  1. 2

                                                                    I should use a thesaurus more before I comment, I think.

                                                                    If the idea is how to stretch your money to attain financial independence, then it does make a lot more sense to me. In my head, achieving that is different from retirement, although it would facilitate an early retirement.

                                                                    About frugality, that is a case of in my vocabulary it carries the meaning of scrimping and saving, rather than good management and thriftness.

                                                                    I guess I do understand…

                                                                    1. 3

                                                                      I think a lot of people have the same association. If I started again I would explain it like: employment is a way to trade time for money, and you want to do it efficiently rather than just rolling with the default setting, and here are some surprising zones of efficiency that don’t seem to be well known.

                                                              1. 12

                                                                Step 1: build a simulator. Anyone who doesn’t do this is building a very buggy system.

                                                                After you have the experience of building your first distributed system on top of a simulator that induces partitions / delays etc… you will forever consider writing them without a simulator to be like driving drunk and blindfolded. So many bugs will pop out. Our laptops don’t behave like networked systems. If you built a plane in windtunnel with zero induced turbulence effects, would you then fly that plane? Because that’s how people are building the distributed systems you use today, and fixes only happen occasionally when someone is lucky enough to realize there’s even anything wrong. They would save so much time debugging high-cost issues in production if they had tested the thing with a simulator.

                                                                But it’s not complex to build a simulator. Much simpler than the subtleties of CRDT convergence with dynamic membership or raft with a single partition that causes dueling candidacies etc… And if you write a few simple tests, like “is the sequence of observed client responses actually possible to observe with any combination of client requests (possibly dropping ones where responses were not observed) executed serially?” which gives you a straightforward linearizability test. You can write simpler invariants that get executed after each message is delivered and processed, like “are there more than 1 leaders that can convince a majority of the cluster to do as they say?” (split brain).

                                                                Simulators give you implementations that Jepsen will not find bugs in, at least as far as the core state machine for your distributed algorithms is concerned. It takes 5 minutes to run 1 jepsen test on a cluster, usually after spending 1 month to implement jepsen for the system, or paying someone hundreds of thousands of dollars to do it for you. You can run thousands of interesting workloads per second on a laptop, stretching the possible delivery horizons for messages way farther, and finding far more bugs.

                                                                You can choose your timing assumption model, but the simplest to implement, and also the one that guarantees the freedom from the most bugs in the wild, is the asynchronous model, where any message can be arbitrarily delayed (maybe forever, dropped) or reordered with others.

                                                                This is one possible interface that has worked well for me:

                                                                // called when this state machine receives a message,
                                                                // responds with outgoing messages
                                                                fn receive(msg, at) -> [(msg, destination)]
                                                                
                                                                // periodically called for handling periodic functionality,
                                                                // like leader election etc...
                                                                fn tick(at) -> [(msg, destination)]
                                                                

                                                                Recipe:

                                                                1. write your algorithm around a state machine that receives messages from other nodes, and responds with the set of outgoing messages. this can be easily run on the simulator in testing, and on top of a real tcp/whatever transport in production. if you have things like periodic leader elections etc… you can implement a tick method also that occasionally gets called. having this clear mapping from input to output is an amazing advantage for taming the complexity of your system, and gives you lots of wonderful introspection opportunities as well if you’re using tracing or anything like that. having total separation between IO and algorithmic concerns will allow you to be much more flexible with how your nodes communicate with each other over time, and will make integration costs lower as well.
                                                                2. randomly generate a set of client requests that happen at a specific time to “seed” the cluster, optionally also seed it with ticks etc… you can be creative here based on what your system actually is doing
                                                                3. stuff all messages / events in the system into a priority queue keyed on next delivery time
                                                                4. iterate over the priority queue, delivering messages to the intended state machine
                                                                5. for each outgoing message in the set that the state machine generated in response, deterministically assign a “delivery time” to the message (or drop it). insert each scheduled message into the priority queue
                                                                6. iterate over the priority queue until empty / some other budget
                                                                7. for each observed client request -> response pair, make assertions about validity of that observed response. Did a write request observe a successful response before a read request, but that read request returned the old value? This will be highly specific to your system, but will save you time by specifying in code.

                                                                This general pattern is called “discrete event simulation”. If you’re coming into distributed systems, if you learn this technique, you will have a massive advantage over anyone who claims to be a distributed systems expert but just tests in production / their laptop / jepsen.

                                                                1. 2

                                                                  “Step 1: build a simulator.” “Simulators give you implementations that Jepsen will not find bugs in” “This general pattern is called “discrete event simulation”.”

                                                                  In short, do what FoundationDB did to get systems so robust that Jepsen team doesn’t think they would find enough to merit a test. :)

                                                                1. 12

                                                                  This “try multiple algorithms until one of them happens to work” approach is profoundly unethical — especially since we don’t have separate training, test, and validation sets — but at least we’re being honest about what we’re doing, instead of inventing a fancy-but-obfuscatory technical term like “ensemble methods” or “hyperparameter tuning”.

                                                                  I really enjoy the spirit of SIGBOVIK :)

                                                                  1. 1

                                                                    God every time I read ensemble methods in a research paper grr

                                                                  1. 5

                                                                    I’ve experienced the same effect working with Erlang, Haskell, and now Rust, where the people who were there were often there because of passion instead of being thrown into that bucket by management or because that is the language that is likely to be chosen due to industrial trends. Being able to acquire professional-grade skills in niche languages often has the false appearance of being a luxury that is unlikely to pay off for your career.

                                                                    None of these languages are hard to learn, given enough freedom and incentives in your life to pursue them. But most people are thinking about keeping the bills paid and staying employable, and niche languages can feel difficult to justify the time investment in.

                                                                    Personally, I’ve found my investments in these languages to let me work on teams full of passionate and productive engineers. It’s easy to become a recognized voice in a small community, and the job offers become much more interesting. And by being one of the few companies working in that niche language in a city, I’ve been able to hire excellent talent for low effort.

                                                                    The same was true for pre-1.0 Go, but it quickly graduated due to becoming quite easy to gain professional-grade skills in, and it’s clear that if you want to build services that you’ll be able to find companies who want to pay you to do so if you know a bit of Go. Now you can get the 10k foot view of how things work in a weekend, which is wonderful for opening up that community, but I think this effect has been lost in that community due to proficiency having fewer preconditions.

                                                                    1. 10

                                                                      The comment section on the linked post is is full of people getting upset at the very idea of someone not liking Rust. Never seen that before…

                                                                      1. 10

                                                                        Never seen that before…

                                                                        It seems common enough to me. At least I have seen it in action plenty of times, especially over on HackerNews. There is even a joke/moniker for it: “Rust Evangelism Strike Force”. People tend to get very worked up and defensive about things they like I suppose.

                                                                        Do note that it definitely seems, based on what I have read, that such behavior is generally frowned on by the Rust team itself. It also /maybe/ doesn’t seem quite as prevalent as it used to? Not sure.

                                                                        1. 4

                                                                          Yes, there is an ongoing significant effort by many of the people in the Rust community to actively work against aggression. There are a lot of messages happening behind the scenes on the platforms that support it where people will be asked to use language that will be more welcoming.

                                                                          1. 5

                                                                            Yeah I was being sarcastic :)

                                                                            Do note that it definitely seems, based on what I have read, that such behavior is generally frowned on by the Rust team itself.

                                                                            Given that people like Steve Klabnik do it on reddit all the time, I doubt that’s the case

                                                                            1. 10

                                                                              Steve can often be seen disagreeing with things he views as mischaracterizations, usually in a pretty respectful way. I can’t think of an example of him being upset that someone didn’t like rust though.

                                                                              I think people sometimes get the impression that he is on the RESF because he can be seen engaging everywhere, but he’s really advocated strongly for NOT doing what you describe. If you’re everywhere, you tend to get associated with the people who might seem to be “on your side” even if they are going about that in a way that you really disagree with. I don’t think Steve would consider people on the RESF to be on his side at all, though.

                                                                              1. 2

                                                                                Well, also cuz it was his job to be everywhere promoting it. All the community team members have publicly denounced the kind of behavior in that comment thread, though. They know it’s not good for their goals. Certainly not coming from them. Just Internet as usual.

                                                                          2. 6

                                                                            I’ve seen it often enough that I don’t bother talking about Rust any more.

                                                                            I’m a C++ developer, but I keep an eye on Rust and Go just to stay up on what’s going on in “systems languages”. I’ve mentioned several times that I don’t see a big advantage to using Rust, since I already know C++ well enough to avoid most of the errors Rust solves. Valgrind, Coverity, and newer C++ features like shared_ptr can eliminate a lot of the errors that Rust tries to solve.

                                                                            But according to some Rust zealots, there’s no way that’s true, and the mere fact that I’ve suggested it means I’m ignorant to the problem and I’m causing buffer overflows left and right.

                                                                            EDIT: Too early, took me a minute to notice it’s sarcasm

                                                                            1. 3

                                                                              newer C++ features like shared_ptr can eliminate a lot of the errors that Rust tries to solve.

                                                                              unique_ptr is slightly harder to misuse, IMO. shared_ptr preserves the ownership quandary that Rust helps mitigate.

                                                                              Undefined behavior is everyone’s nemesis, IMO. UBSan helps but

                                                                              I already know C++ well enough to avoid most of the errors Rust solves

                                                                              And so you probably know it well enough to recognize the bugs you’ve introduced when you’ve spent some time debugging an issue.

                                                                              Valgrind, Coverity, and …

                                                                              IMO if you value static checkers like Coverity’s, then it stands to reason that you might like a Sufficiently Smart Static Checker. But if C/C++ had to be constrained to a subset of the current language in order to give that Sufficiently Smart Static Checker the additional context it needed to find bugs, would you still find it interesting? If the answer’s “yes”, then it seems to me like Rust isn’t far from what you’d get from a constrained C++. If the answer’s “no” then maybe C++ is ideal for your use.

                                                                              cargo and the crates infrastructure is Rust’s big win, in my opinion. Safety features are just the entrance criteria for a new language.

                                                                              1. 1

                                                                                I’m not a Rust zealot, but I settled on the default approach of “if you are using C or C++ for new things in 2019, there is something going horribly wrong; but I’m open to hear the reasoning to convince me otherwise”.

                                                                                Nothing is worse than C/C++ developers thinking they understand their language, despite a million man-decades of evidence pointing to the exact opposite.

                                                                                1. 6

                                                                                  There is a difference between knowing it well enough to write a compiler compliance suite, and knowing it well enough to quickly deliver business value.

                                                                                  Please do not keep parroting the same “C/C++ is evil” meme, and certainly don’t lump them together.

                                                                                  1. 3

                                                                                    The only difference is whether the result of not knowing it well enough will kill people or just slightly reduce some business value (isn’t it crazy how C and C++ have trained the general populace to not even expect programs to be reliable?).

                                                                                    Please do not keep parroting the same “C/C++ is evil” meme, and certainly don’t lump them together.

                                                                                    It took people a few decades to figure out that smoking kills, so regardless of whether you consider it “evil”, I hope that in the future C++ compilers ship with mandatory shock pictures that show the consequences of using C++.

                                                                                    1. 3

                                                                                      isn’t it crazy how C and C++ have trained the general populace to not even expect programs to be reliable?

                                                                                      Please provide evidence for such big claims. As a personal anecdote, I have to deal with much more unreliability caused by Java software than by C/C++.

                                                                                  2. 1

                                                                                    FWIW, this is exactly the type of response I was talking about. You’re right, obviously I have no idea what I’m doing.

                                                                                    I’m not interested in this tedious argument, so I won’t be replying again.

                                                                                2. 2

                                                                                  Yeah, there were some assholes in there. They should knock it off given it’s certainly not doing any favors for Rust adoption or even making new friends who work on cool projects like Dust3D.

                                                                                1. 1

                                                                                  TLDR: he went back to C++ because he was adding too many “unsafe” Rust blocks - that is, he didn’t grasp Rust core principles yet.

                                                                                  1. 10

                                                                                    Do you realize that your comment is very similar to some C and C++ experts saying that people have security vulnerabilities because they’re not experienced enough?

                                                                                    1. 10

                                                                                      No, it’s actually just hard to learn Rust due to how the borrow-checker forces you to change your design and coding habits. It’s a wall all the newcomers hit. In the article, the author even mentions this:

                                                                                      “ I know the friction is greater because I am still a Rust learner, not a veteran”

                                                                                      Author then says they’re trying to write the kinds of data structures that Rust team says are the hardest to borrow check. That’s a huge jump. The Rust team usually tells people to avoid stuff like that in favor of easier examples. People can gradually pick it up. There’s also resources out there like the linked lists article to help speed the process up. One other thing I hear developers mention is using a data-driven design rather than control-flow-oriented design helps, too. I’m still unclear on fully what that means but quite a few say it. Gotta be an article somewhere…

                                                                                      Long story short, he’s an amateur at Rust applying it to the hardest problems. He should probably stick to C, C++, or unsafe Rust for the hardest stuff. He can rewrite those components later in safer Rust if he figures out how. I tend to just Google stuff like this in case others ran into same problems. Found one BST article. Anyone that can read Rust tell me if that one borrow checks?

                                                                                      1. 4

                                                                                        When they say “data-driven” design, they’re pointing you towards a more ECS-like design. You can see an example of how this plays out on the GUI side in this talk: Data Oriented GUI in Rust by Raph Levien - Bay Area Rust Meetup

                                                                                        In short, rather than a tree of widgets, where each widget ends up with a reference to its children and its parent, you end up with an array of widgets, each of which is identified by its index in that array. Now when you want to refer to a widget you’re just indexing into an array rather than dereferencing a pointer. This plays well with the borrow checker.

                                                                                        1. 1

                                                                                          I’m wondering in which way this index-based approach is superior to unsafe code? I don’t really know Rust but to me it seems like sidestepping the problem since you can easily end up with indices that point to freed or invalid array elements.

                                                                                          In other words, many compile time guarantees are lost.

                                                                                          1. 3

                                                                                            I believe it’s a kind of a compromise. In that you still may get logic errors, but at least consequences won’t be so dire and will be easier to track. With unsafe blocks, you’re getting back to Undefined Behavior-like territory, basically risking memory corruption and sabotaging of any typesystem guarantees.

                                                                                            1. 1

                                                                                              Fair enough. Having hunted my share of nasty buffer overflow bugs, I can definitely see the benefit here even though logic errors are not caught at compile time.

                                                                                            2. 3

                                                                                              I’ve seen some approaches that use “generational indices”, which is basically where you store a tuple of (generation, item) as elements in the array, and your “reference” to that item is (generation, index). If you update the item, you bump its generation. Then when you go to access the item you compare the generations. If they don’t match, that means your “reference” is stale, and you can handle that however you want.

                                                                                              1. 3

                                                                                                this is what jonathan blow pointed out, there was a ton of discussion around it:

                                                                                                https://www.youtube.com/watch?v=4t1K66dMhWk (the jblow rant)

                                                                                                https://www.reddit.com/r/rust/comments/9fqget/jonathan_blow_entity_systems_and_the_rust_borrow/

                                                                                                I feel like it was discussed a lot on HN and maybe here too but I can’t find it.

                                                                                              2. 1

                                                                                                Thanks! I’ll check it out.

                                                                                              3. 2

                                                                                                No, it’s actually just hard to learn Rust due to how the borrow-checker forces you to change your design and coding habits. It’s a wall all the newcomers hit.

                                                                                                Yes and it’s actually hard to learn safe C/C++. As @azdle pointed out below, my issue with the comment was the generic dismissal of real problems that people face with Rust, which robs us of an objective opinion of what to expect from migrating to it.

                                                                                                Long story short, he’s an amateur at Rust applying it to the hardest problems. He should probably stick to C, C++, or unsafe Rust for the hardest stuff. He can rewrite those components later in safer Rust if he figures out how. I tend to just Google stuff like this in case others ran into same problems. Found one BST article. Anyone that can read Rust tell me if that one borrow checks?

                                                                                                The point is, that those are hard problems in Rust, and not in other languages, and the author doesn’t wanna waste time doing it in Rust, when they can do it much faster in C++. What I understood was that the author just wants to work on Dust3D, and not on programming languages.

                                                                                                1. 1

                                                                                                  my issue with the comment was the generic dismissal of real problems that people face with Rust

                                                                                                  I certainly wouldn’t want that. Another person was griping about the FFI. I expect most new languages to have a hard time integrating with C++ code. I expect indirections which might hurt performance too much. So. there’s another objection that was valid on top of learning borrow checker.

                                                                                                  “that those are hard problems in Rust, and not in other languages,”

                                                                                                  They are hard problems in other non-GC languages if your goal is temporal safety and race freedom. Even OpenBSD with its great coders kept having temporal errors. The races are often heisenbugs difficult to track down. Having the compiler guarantee these properties are preserved on all inputs is something C and C++ don’t have that I’m aware of.

                                                                                                  Now, let’s say you don’t need them. You might not need Rust given that’s one of main selling points. Let’s say you don’t always need them which is consistent with OP. As in, a few data structures were too hard to do. I’ll point out something folks rarely bring up in these discussions: Rust can do both unsafe and reference-counted pointers. As in, you can drop down to C or C++ style on any module it can’t handle wrapped in a type-safe interface optionally with input validation. Then go right back to safe-by-default code for majority of the app with lower defects and panics instead of code injections. That’s still better defect vs effort ratio than C or C++.

                                                                                                  At that point, the borrow checker is no longer a negative. The FFI situation could still mess the author up, though. Also, two languages with lots of typing that might not mix well. Might be too much pain to justify except for critical applications.

                                                                                              4. 2

                                                                                                You’re just asking for a “Do you realize that your comment is very similar to those people saying that if a programming language is difficult then it is not worth adopting?” reply.

                                                                                                Rust was literally born as a reply to those experts you just named. And if a programming language doesn’t change the way you think, then it’s not worth wasting time on it.

                                                                                                I wouldn’t have posted that comment if the author said “I’m not yet comfortable with officially releasing Rust code while I’m still learning”, or something like “I had to switch back because currently I find it easier to maintain C++ code”.

                                                                                                No. His point was all about tricking the Rust compiler to get problems solved. Add an unsafe and the borrow checker stops complaining. Oh boy.

                                                                                                1. 1

                                                                                                  Rust was literally born as a reply to those experts you just named.

                                                                                                  Which is why I find your comment ironic. It’s a bit hypocritical in my opinion when someone starts using the same methods they argue against.

                                                                                                  I wouldn’t have posted that comment if the author said “I’m not yet comfortable with officially releasing Rust code while I’m still learning”, or something like “I had to switch back because currently I find it easier to maintain C++ code”.

                                                                                                  No. His point was all about tricking the Rust compiler to get problems solved. Add an unsafe and the borrow checker stops complaining. Oh boy.

                                                                                                  I don’t think this is a fair understanding of the author’s intent. Let me quote them:

                                                                                                  Given so many advantages, why I am switching back to C++? The most beautiful thing about Rust is also a disadvantage. When you implement an algorithm using C++, you can write it down without one second of pause, but you can’t do that in Rust. As the compiler will stop you from borrow checking or something unsafe again and again, you are being distracted constantly by focusing on the language itself instead of the problem you are solving. I know the friction is greater because I am still a Rust learner, not a veteran, but I think this experience stops a lot of new comers, speaking as someone who already conquered the uncomfortable syntax of Rust, coming from a C/C++ background.

                                                                                                  I think this is a fair criticism. You and others are saying the author has to change the way they think and approach problems differently, mainly from rust’s point of view, the author on the other hand just wants to use an already existing algorithm verbatim, and doesn’t wanna look for different algorithms that would fit the rust model more. How is this about tricking the borrow checker?

                                                                                                  Also the author further goes on to say:

                                                                                                  Another reason is the Rust ecosystem is still immature. As an indie game developer I can see the situation is changing, there is a website Are we game yet? that lists many neat things in the Rust world, there is a data driven game engine written in Rust called Amethyst, all these things look really promising. But, there is no Qt, no CGAL etc, all these frameworks and libraries have been developed for so many years and maintained very high level of quality. I know there are some bindings, but it’s not mature and not enough.

                                                                                                  which to me is completely different to the TLDR you provided.

                                                                                                  1. 1

                                                                                                    When you implement an algorithm using C++, you can write it down without one second of pause, but you can’t do that in Rust.

                                                                                                    You can’t if you want it statically guaranteed to be safe. You can using other mechanisms if you don’t care about that. So, author is incorrect.

                                                                                                    Now, I can’t tell you if doing it another way will cause any conflicts when integrating into existing ecosystem of Rust crates. I don’t know if they expect code calling their functions to borrow check in a way that will cause a different, compiler warning. Worth some experiments. If not, then the primary gripe about Rust goes away whenever you want it to.

                                                                                                    “But, there is no Qt, no CGAL etc, all these frameworks and libraries have been developed for so many years and maintained very high level of quality.”

                                                                                                    One of the best reasons not to use Rust in that niche. Hard to say how difficult it would be to wrap or port any of that.

                                                                                                2. 0

                                                                                                  no, no its not.

                                                                                                  in fact its the exact opposite of that - “unsafe” is not the default in Rust - OP would have to explicitly add the “unsafe” keyword to enable this behavior

                                                                                                  if he chooses to do that then the consequences are his fault - unlike in C++ when “unsafe” is essentially the default

                                                                                                  stop posting misinformation.

                                                                                                  1. 4

                                                                                                    I don’t know that you meant it this way, but your comment comes off as a rather rude out-or-hand dismissal, which is especially unfortunate because I think you misunderstood what nullp0tr meant.

                                                                                                    You’re correct about your description of how unsafe works, but the way I understood what they mean was more about generic shallow dismissals of problems that people new to the language (or just people from the fact of being human) have with a language.

                                                                                                    The “solution” to both problems here is “be more experienced” and “don’t do it wrong”, which really aren’t helpful.

                                                                                                    1. 2

                                                                                                      Exactly what I meant! thanks for being understanding:)

                                                                                                3. 9

                                                                                                  he didn’t grasp Rust core principles yet

                                                                                                  Or, unsafe is still needed quite often when doing low level/performance sensitive work.

                                                                                                  1. 3

                                                                                                    “Quite often” is debatable. If you need many unsafe‘s then either you’re cutting too many corners or you’re not using appropriate type definitions. Or you think you can outsmart the LLVM optimizer every time you fancy to.

                                                                                                  2. 5

                                                                                                    It honestly took me about 2 years of bursty usage before I started feeling like I could really fly. Things are in a far, far, far better place now for newcomers, but that feeling of being unable to express yourself is going to exist until you have the time and resources to really understand borrowing.

                                                                                                    I really like this post that drills into it: Rust: A unique perspective. For me, it really started making sense when I started thinking of immutable references as being similar to a reader lock, and a mutable reference as being similar to a writer lock, since I had done a bit of concurrent programming before coming to Rust. But everyone has different metaphors that they will need to find. People come to Rust from a ton of different places, it’s not just another exodus-from-X but it pulls people in from front-end, back-end, embedded, databases, distributed systems, etc… But resources targeted at people with different backgrounds are starting to pop up more and more to make the process faster for them.

                                                                                                  1. 2

                                                                                                    To make a type that can never be created, simply create an empty enum. Use this where you want to prevent compilation of specific codepaths.

                                                                                                    What does that mean, prevent compilation of specific code paths? When are we writing code paths that we don’t want to compile?

                                                                                                    1. 2

                                                                                                      For example, som API might be expecting a Result<V,E> type, but your specific operation can never fail. Then if you use the empty enum mentioned as the E-type, the compiler will know that there will never be an error and can remove all the error handling around your operation.

                                                                                                      There are plans to add a specific type to rust denoted !, called the never type, that has this specific meaning. Unfortunately the never type is problematic, so it has been delayed quite some time.

                                                                                                      1. 2

                                                                                                        On stable you can use ! for functions that never return, which is helpful in embedded where main should never return, or to make match arms typecheck when one of them exits the process, like a usage statement.

                                                                                                    1. 2

                                                                                                      Is this still accurate in 2019? I guess kernels’ internals algorithms have not changed too much since 2006. However, CPUs today have much more cache (especially server-grade CPUs), and servers can have plenty of RAM, thus avoiding excessive swapping.

                                                                                                      1. 7

                                                                                                        PHK knows enough about the filesystem to use it right. Most people don’t understand the correctness and performance issues at play when using files in performance sensitive environments, and should use a database instead. And if you’re building a database, there’s a pretty high chance you’ll want to bypass the pagecache by using O_DIRECT so you can have very fine-grained control over the order that IO is performed in, letting you reason about your own guarantees in your crash recovery logic and generally making it more clear how to scale up writes to utilize hardware.

                                                                                                        Kernels have generally not provided users with the interfaces required to keep up with the dramatic improvements to storage performance that have been happening since the PHK article. Linux is getting io_uring very soon which will be a really major step to unlock higher performance in a decent API and not having to take the hard paths of AIO / SPDK / lightnvm etc… But I’m not sure where the line will be between people using io_uring and people using a database that does it for them.

                                                                                                      1. 16

                                                                                                        some modern linux exercises if you haven’t narrowed down your own yet, and want to just jump into kernel hacking:

                                                                                                        • start with a small loadable kernel module that logs a message with pr_info that you can read from dmesg
                                                                                                        • have your kernel module create a procfs entry that can be modified from userspace to get information into the module
                                                                                                        • modify kernel/sched/core.c (formerly sched.c) to read a number from procfs and bias the scheduling algorithm to blacklist it from ever running. test by starting a userspace process that print in a loop, write its pid to procfs, see if it stops or not
                                                                                                        • introduce a subtle bug in the scheduler (if you were fortunate enough not to have in the last step) and use qemu + gdb to peer into it at runtime
                                                                                                        • implement a new syscall, call it from userspace
                                                                                                        • intentionally introduce a memory corruption bug and use kasan to catch it

                                                                                                        kernel dev is more of a human political problem than a technical one, and every kernel subsystem has its own way of doing things, but there’s a lot of overlap. whatever subproject you want to join or create, learn enough about its human operations so that you can be respectful. this will involve reading a bit of process documents, learning new tooling, and still probably leaving you with a sense of uncertainty about where to jump in. some projects are more newcomer friendly than others.

                                                                                                        it’s easy to do cool hard stuff by yourself, but with kernels it’s much more of a coordination problem, so respect the people by doing your homework before spending their time, then you can have the confidence to ask them for advice knowing that you have done your homework (you can also ask people HOW to do your homework so you can prevent wasting more of their time if a subproject doesn’t make it easy to find) and you’ll find someone who will be willing to point you in the right direction

                                                                                                        1. 1

                                                                                                          Those projects seem like a nice entry point. Thanks for the advice regarding the soft-skills too.

                                                                                                        1. 13

                                                                                                          In Rust, I ended up using tokio, but I think that was a mistake.

                                                                                                          It was. Once async/await is stable, the event-based story should be much better, but as is Futures are a pain to use. I’m using actix-web currently, and I spend most of my time fighting the type and borrow checkers. Outside of Futures, I never find myself fighting with the borrow checker anymore, so that’s saying a lot.

                                                                                                          I’m greatly looking forward to async/await stabilizing, but for now, if writing your own library, I would suggest either blocking + threads, or raw mio. In the latter case, it should be trivial to add an adaptor once async/await stabilizes.

                                                                                                          1. 7

                                                                                                            I’m also happy to see stuff like may which provide stackful coroutines without very much cruft at all. Async/await will also be another huge win for cruft-reduction in the async space. As someone who writes large codebases in Rust, I tend to stay away from the current stable async stuff in most cases (unless I write my own simple thing directly on top of mio) due to the stack explosions and general code complexity issues that pop up for little gain over threads unless you’re building a load balancer. Many people are not building load balancers, but get pulled into the async hype because it’s what gets blogged about, and then they end up with combinator chains 7 indentations deep and it takes them 6 hours to change a line of business logic. Async/await will mean that they get to live in a hyped ecosystem (which can be really fun, and fun is a major factor for sustained productivity) without nearly so much ergonomic strain. If you want to look at the future, check out the romio crate which is tokio adapted for the upcoming world of async-await, and is a pleasure to work with.

                                                                                                            Other than choosing the wrong tool for the job, I think a big issue, which rust could do better about as well, is the 3-pages-of-errors due to being unable to unify code that doesn’t typecheck. The way that rust does type inference is by starting with the function’s arguments and return type, and working one step at a time in both directions (down based on arguments, up based on return type) through the function body. This is one of the reasons why rust can’t infer the type arguments for functions. But as a result of this, if a bunch of code in the middle of a function is invalid because there is a gap in the “evidence chain” about what it should be, then it will emit errors about it all. For this reason, the most efficient way to debug these long pages of errors is to start at the edge of unification, and either work your way down or up from there. I usually pipe cargo’s output into head because I only care about the first one most of the time, but this is tribal knowledge, and maybe it’s possible for the compiler to reduce its volume a little bit, and stick to the current edge of unification in some cases.

                                                                                                            1. 2

                                                                                                              Got any more tribal knowledge for working through rust type errors? This is useful!

                                                                                                              1. 4

                                                                                                                Another big one is window switching fatigue. It’s common to see students in my rust trainings do this dance:

                                                                                                                1. guess about a code change to please the compiler
                                                                                                                2. save
                                                                                                                3. manually switch to terminal and run cargo build/run/etc…
                                                                                                                4. see 1000 errors
                                                                                                                5. scroll to top (or worse, try to fix random errors that don’t matter by adding type info that would have been populated automatically if the first error was fixed)

                                                                                                                It’s all about keeping the cycle short. I have this command aliased to a convenient shortcut and I keep it running in the other terminal, which automatically detects file changes and skips the llvm pass:

                                                                                                                cargo watch -s 'clear; cargo check --tests --color=always 2>&1 | head -40'

                                                                                                                which reduces the dance to:

                                                                                                                1. attempt fix
                                                                                                                2. save
                                                                                                                3. see most relevant errors without switching to the terminal or scrolling

                                                                                                                cargo watch will run a specified command every time your files change, defaulting to cargo check, but I like to pipe it through head to keep it short and I don’t have to scroll. cargo install cargo-watch will install this watcher plugin. cargo check skips the llvm compilation step, you can use cargo run or cargo test here too depending on the thing you’re trying to do.

                                                                                                          1. 12

                                                                                                            This is a little off-topic, but I wonder if companies choose to use complex solutions such as a SPA or Kubernetes to attract and more importantly, retain talent. If you’re trying to get experience in the industry (ages 22-28 usually) to build a solid career, would you rather work at a place that uses the latest tool so you can put it in your résumé? The code quality or technical debt is irrelevant - you will most likely work somewhere else in a few years.

                                                                                                            This even happens with companies that do use SPAs. On HN I read a comment from someone at a company using Ember saying they have a hard time hiring because people want React experience instead.

                                                                                                            1. 3

                                                                                                              My company is exactly doing that, the engineering management forces the teams to adopt latest technologies because it’s a pain to recruit in our area without “cool” technologies.

                                                                                                              So it’s down to “go + react + kubernetes”…

                                                                                                              1. 2

                                                                                                                If companies paid developers what they were worth and gave them a real stake in the profits they generate they wouldn’t have to play stupid games with shiny technology.

                                                                                                                However, techies are generally stupid short-sighted and are willing to chase shiny instead of getting paid. This hurts all of us.

                                                                                                                1. 2

                                                                                                                  This sounds very plausible to me. I feel like you’d be considered a dinosaur for using Ember nowadays. Perhaps using the word “nowadays” would also encourage the same label :)

                                                                                                                  I’m now using jQuery again because of a code base I inherited at work.I feel like a certain segment of the population would find that fact appalling or, at the very least, strange.

                                                                                                                  1. 2

                                                                                                                    Absolutely. Talented people got that way because they like to learn. If you want to acquire and keep them, you have to provide them with opportunities to learn the things that they want.

                                                                                                                  1. 11

                                                                                                                    Another Dockerless alternative: put your data directory on a tmpfs file system. If you want to make setup a breeze, you can keep your pre-start state on a real disk and rsync it to tmpfs at the start of every test run.

                                                                                                                    For mysql, other than what folks have already said, you can use the MEMORY engine for your database.

                                                                                                                    1. 1

                                                                                                                      for testing the sled database a few thousand times per day I do something similar by running most tests in /dev/shm

                                                                                                                    1. 4

                                                                                                                      Sounds like all these arguments apply to any threading program. Go is not the same as Goto because you keep your thread of execution, despite adding another.

                                                                                                                      1. 2

                                                                                                                        Yes, they do apply to any threading program, which is the point—you’re applying the analogy too literally. Goto is a low-level mechanism that was (largely) replaced by a higher-level mechanism (structured programming) that did the same work in a much more understandable and reliable way. In SAT terms, goto is to structured programming as today’s thread APIs are to structured concurrency.

                                                                                                                        1. 2

                                                                                                                          We did have C style concurrency with pthreads, that just sucks. The go statement gives us back our ability to thread without the boilerplate. Nurseries remove the ability to “just take care of it while I’m not looking” with more boilerplate.

                                                                                                                          1. 3

                                                                                                                            Are the if/then and for statements just more boilerplate too, then?

                                                                                                                            1. 0

                                                                                                                              Yes. If we could do with zero boilerplate we would. Look at Shell with its && and || making it fast to test assumptions without the boilerplate of an if.

                                                                                                                              1. 5

                                                                                                                                Any time I look at raw TLA+ I’m reminded of how much I appreciate abstractions above logical dis/conjunction

                                                                                                                            2. 2

                                                                                                                              The article literally lists pthreads as an example of the “go statement.”

                                                                                                                        1. 1

                                                                                                                          This connects pretty well with how I like to introduce these concepts while giving rust trainings. Thinking about mutable vs immutable borrows similarly to RwLocks (for crowds that have concurrency experience) really makes it click effectively.

                                                                                                                          1. 4

                                                                                                                            The bit about how it’s hard to tell what will close a Reader/WriterCloser underneath you is super valid. I’m not sure how you’d manage that without some kind of “reference count” or similar (i.e. only actually close until the count hits zero).

                                                                                                                            Another awkward use case is how to write http middleware that hash-sums a post body (i.e. for slack webhook validation) and then also lets inner actions read from the request post body.

                                                                                                                            1. 6

                                                                                                                              It’s simple. If you pass a *Closer to something, you should assume that something is going to close it. Otherwise you’d just pass it a Reader or a Writer.

                                                                                                                              1. 2

                                                                                                                                Not everyone gets the memo that this is the way it’s supposed to work. Very often, folks will create large interfaces and pass them around, with no intent on using everything defined.

                                                                                                                                1. 2

                                                                                                                                  Sure, but at a certain point, what can you do about people ignoring the docs and even the sort of high level guidance of the language? I mean, deep reading docs is hard, reading the go proverbs isn’t https://go-proverbs.github.io/ – and you only have to get to the 4th one to get to “The bigger the interface, the weaker the abstraction.”

                                                                                                                                  1. 5

                                                                                                                                    “The bigger the interface, the weaker the abstraction.” says very little to someone not engaged in deeply understanding it.

                                                                                                                                    Obviously, we can’t throw our hands up and say, “what can you do? People will be people!!!” What we can do is ensure that code we write and review takes these principles to heart, and shows the value of it.

                                                                                                                                    1. 2

                                                                                                                                      Absolutely, and after doing all that – people are still going to write terrible code that directly goes against all the norms and recommendations. I am all for doing our level best to try to guide people – but leading a horse to water and all that.

                                                                                                                                2. 1

                                                                                                                                  I think this is true, but it basically means you should never pass a *Closer unless you really really have to. The callee should manage the IO lifecycle.

                                                                                                                                  I would even go so far as to say one of the heavily opinionated Go linters should warn (maybe they do, I have never checked because I don’t think highly opinionated linters are a good idea for anything but beginners).

                                                                                                                                  1. 1

                                                                                                                                    This makes sense, but two difficulties.

                                                                                                                                    1. Still requires careful analysis of docs. It’s very easy to pass a closereader off to a function taking a reader.

                                                                                                                                    2. You can’t just pass something like a gzip.reader to another layer. Even if that layer closes, it doesn’t close the bottom.

                                                                                                                                    1. 1

                                                                                                                                      When I read stuff like this I change my mind about go being a language that can be learned in a weekend.

                                                                                                                                      1. 1

                                                                                                                                        You can certainly pick it up and use it effectively in a weekend, but surely you couldn’t learn the ins and outs of anything substantial in just a weekend.

                                                                                                                                    2. 4

                                                                                                                                      Between io.TeeReader and io.Pipe I think you can probably wire something up. There’s a decent amount of “plumbing” included, although it took me a few passes through the docs to find it all.

                                                                                                                                      1. 4

                                                                                                                                        Yeah, its quite worth it to read through the whole std library docs, I seem to find a new thing each time I skim it again.

                                                                                                                                      2. 1

                                                                                                                                        how to write http middleware that hash-sums a post body (i.e. for slack webhook validation) and then also lets inner actions read from the request post body.

                                                                                                                                        I’ve had to do something like that and I ended up writing a small TeeReadCloser struct that wraps TeeReader but also has a Close method that closes both the reader and the writer. You can probably get by with a version that takes a WriteCloser like mine and one that just takes a Writer and combine them as needed, though I wonder why they couldn’t just put these in the standard library.

                                                                                                                                      1. 8

                                                                                                                                        I’m not a fan of n-gate. (I have no general issue with the profanity, I just don’t find it creative. Read one, read all.)

                                                                                                                                        Still, I’m a bit surprised that it doesn’t lose a word about Rust, one of his hot topics in the last years :). We made it :).

                                                                                                                                        1. 8

                                                                                                                                          I just don’t find it creative. Read one, read all.

                                                                                                                                          Counterpoint: Medium blogs, of which we must suffer an endless barrage.

                                                                                                                                          1. 6

                                                                                                                                            It’s not a tug of war, both can have this quality.

                                                                                                                                          2. 2

                                                                                                                                            Maybe he just got bored with the repetition. It was getting redundant even to him. It was leave it off for a day or troll himself about it.

                                                                                                                                          1. 7

                                                                                                                                            This is a pointless article, really. There are so many ways of doing safe concurrency in Haskell, and yet, the author chooses a very unidiomatic unsafe way, which happens to highlight Rust’s type system’s fundamental strength. The one thing the whole language is built around.

                                                                                                                                            What’s at fault here is the secret function. You can’t just accept an arbitrary IO action and run it concurrently with any other arbitrary IO action. Haskell gives you so many ways to encode your expectations from your arguments, so secret should be more conservative about what it accepts if it’s planning to run it concurrently.

                                                                                                                                            1. 11

                                                                                                                                              I don’t think it’s pointless. Your argument applies to any language, even C++. C++ gives you primitives for composing safe concurrent programs but I wouldn’t say articles pointing out how hard it is to do so in practice are pointless. The main takeaway from the article is as you said, effectful computation is hard. I don’t think that’s pointless.

                                                                                                                                              1. 9

                                                                                                                                                The difference is that the IO ref he’s using causes a gagging response in a Haskeller, and it’s definitely a red flag that you’ll have to justify rigourously to anyone reviewing your code. Whereas in C++ you’re defining the equivalent of an IORef every second line, so an error like this can easily slip through. In a way, using an IORef is like an unsafe block in Rust.

                                                                                                                                                So, it’s not that Haskell gives you safe primitives, it’s that the natural, easy, idiomatic way to write Haskell is safe.

                                                                                                                                              2. 3

                                                                                                                                                I have a similar reaction to most articles that complain about Rust allowing unsafe things to be expressed. Haskell STM is a dream. Both languages give you plenty of escape hatches that can be misused, but we’re able to write such nice libraries abstracting over the dangerous parts because of them.

                                                                                                                                                1. 1

                                                                                                                                                  I’ve never heard of anyone having a problem with Rust allowing unsafe things to be expressed. I think you’re misrepresenting the argument against how ‘unsafe’ works in Rust.

                                                                                                                                                  The problem is that once you have ‘unsafe’ anywhere in your code, it becomes very difficult to control how much code must be written with that in mind. Changing some code not marked unsafe can create memory unsafety that wasn’t there before. That’s a really bad attribute to have.

                                                                                                                                                  1. 1

                                                                                                                                                    Yup, just like the escape hatches in haskell. We have two usable languages because of them.

                                                                                                                                                    1. 1

                                                                                                                                                      ‘Haskell does it’ is not an excuse.

                                                                                                                                                    2. 1

                                                                                                                                                      The problem is that once you have ‘unsafe’ anywhere in your code, it becomes very difficult to control how much code must be written with that in mind. Changing some code not marked unsafe can create memory unsafety that wasn’t there before. That’s a really bad attribute to have.

                                                                                                                                                      This is also misrepresenting, I must say. unsafe blocks and functions are specifically not allowed to mess with the surroundings. Especially, if you take safe types in and give safe types out (borrows, lifetimes, owned data, etc.), you have to hold all their invariants (e.g. that &mut doesn’t alias). Also, unsafe code might express expectations on the direct caller (e.g. “this function could be called twice to produce two &mut references, which is why it is unsafe and you must make sure that you don’t do this”). But that’s all very localised.

                                                                                                                                                      There’s bugs in implementing this, and they might bite you far down the road, but nothing that people have to keep in mind in the scope of a larger codebase.

                                                                                                                                                      1. 1

                                                                                                                                                        This is also misrepresenting, I must say. unsafe blocks and functions are specifically not allowed to mess with the surroundings.

                                                                                                                                                        They absolutely are allowed to. If they couldn’t mess with their surroundings, they simply wouldn’t do anything.

                                                                                                                                                        Also, unsafe code might express expectations on the direct caller (e.g. “this function could be called twice to produce two &mut references, which is why it is unsafe and you must make sure that you don’t do this”). But that’s all very localised.

                                                                                                                                                        It’s not localised. Any module with unsafe has to be analysed as a whole. You cannot just look at the parts marked ‘unsafe’. If ‘unsafe’ is anywhere in the module, you have to look at the whole module, and the result of looking at the whole module might be ‘the behaviour of this module depends on the behaviour of other modules too, we have to look at all the rest of them’.

                                                                                                                                                        People say things like ‘unsafe is good, because unsafe operations can only happen inside unsafe blocks’. And that’s true, in a sense, but it’s also false in a sense. Unsafe operations in the sense of ‘things that can have undefined behaviour’, yes. Unsafe operations in the sense of ‘things that can cause undefined behaviour later’, no.