1. 3

    Why Does He Do That?: Inside the Minds of Angry and Controlling Men (Amazon) which has been surprisingly eye opening on the habits and motivations of abusive men.

    I just got through Why We Sleep (Amazon), which was good, but surprisingly not that much of an improvement over listening to the Joe Rogan Experience #1109 with Matthew Walker, the author of the book.

    1. 19

      There’s so much excellent content on wiki.c2.com it’s ridiculous. Many of the things people rant about on HN, on Facebook, on Twitter, in their blogs, have already been debated to death over a decade ago on the original wiki. (And probably on usenet before that.)

      1. 6

        At my first job in the early 00’s, c2.com escaped the workplace net filter since it was low bandwidth, so I’d be browsing it whenever I had a free minute.

        I was exposed to more CS concepts in 6mo than the last two years of college. It helped me finally understand functional programming (which I then used on the job with XSLT), and got me learning Ruby&Io(via “what exactly are coroutines?”), which lead directly to my next job.

        1. 1

          Any favorites for learning CS?

          1. 2

            Continuations and Coroutines was pretty mind-expanding for a first page, as I was trying to understand a Tim Sweeney interview comment that monsters in UnrealScript “all moved at the same time”

          2. 1

            This is great to hear someone else had a similar experience. I still (infrequently) point other programmers at it - though wikipedia has lots more of this information now.

          3. 1

            I think I’ve read almost all of several sections of that site.

            Totally amazing and worth the time, even if some pages are not very good.

          1. 4

            Not to spoil the article, but the ending quote in bold really sort of scares me. I’ve spent most of my life hearing stories about how machines will take human jobs. The reality of that has played out much less scary (so far) than they’d have had us believe 20 or 30 years ago. It’s never really occurred to me, though, that in another 20 or 30 years that my job as a programmer might be obsoleted as well. It’s like the matrix; funny ha ha, but for real.

            Thankfully I hope to be retired 30 years from now :P

            1. 4

              I think this is the natural progression of things, isn’t it? Programming isn’t immune to the effects of automation - just the opposite, in fact. It’s like boiling a frog - things are automated so often and so incrementally that programmers no longer notice when jobs that would have taken 10x longer a few years ago are basically instantaneous today.

              1. 11

                Programming will be the last thing to be automated, because it is itself automation - once you have automated programming you just have to run your automated programmer and then you’ve automated everything.

                1. 2

                  …No. The only thing that will save programming from being automated NEXT is… wait, I see what you did there. “Your keys are always found in the last place you look.” :)

                  On a serious note, regarding future job prospects, I think programming will not be the last available job. Some job that isn’t an attractive candidate for automation will be the last available job. Programming, with all its expense, is a prime target.

                  1. 4

                    Once you can automate programming you can automate everything else at approaching 0 cost, so it’s moot.

                    1. 1

                      Can you? I would imagine lots of jobs rely on intrinsically tacit, “local” intuition, and not merely knowledge and cognitive function, which is what it seems to me the only thing that “solving programming” entails automatically.

                      1. 1

                        Programming often relies on intrinsically tacit, local intuition. I mean think of the last time you received feedback from the customer about how they felt the software should work.

                        1. 1

                          Good point I didn’t think about that end of the situation

                2. 2

                  Hopefully, this allows them (and me) to do their (and my) jobs more efficiently, and focusing on other more important things. Of course, other stuff will eventually fall into obsolescence, but don’t we have graveyard keepers, working on decrepit technologies for sizeable amounts of money? COBOL experts, where art thou?

                  1. 2

                    All very true. I think the reality just sort startled me.

                  2. 5

                    This is why it’s important to move past capitalism ASAP: it’s more and more immoral to couple the ability to get a job with the ability to stay alive and retain dignity. Once all labor is automated, there shouldn’t be any jobs (coerced or obligatory labor), and we should all be rejoicing.

                    1. 0

                      Will there still be a free market? Or will what we consume be planned by the machines. At which, point, without the ability to decide what I want - or the illusion thereof - my job as a human is done too …

                      1. 5

                        woe to those who think their job as humans is to consume

                        1. 1

                          I eat, therefore I am.

                        2. 1
                          1. We all make the world;
                          2. define “free market”.
                          1. 0

                            There is a medium of exchange (please not barter) and a market for goods and services. I have goods/services to offer and I have goods/services I need. I have markets to go to sell and buy these. The market is not controlled by the commissariat which determines how much toothpaste I get and what color tube it comes in because for reasons most people can not fathom, I like to chose.

                            1. 1

                              you can chose what color tube your toothpaste comes in?

                              1. 0

                                In capitalist America, toothpaste color chooses you!

                              2. 0

                                What is available in these markets? What is not? How are its dynamics damped, to avoid balloons and crashes? How are negative externalities, like advertising or air pollution, accounted for? You throw around the “free” as though its interpretation were obvious, when the devil is in the details, and the details are everything.

                                1. 0

                                  This is strawman nonsense, and nowhere do I imply central planning. What you’re really saying is, “I want freedom of choice for consumption and production,” which doesn’t require capitalism, though you’re strongly implying you think it does.

                                  1. 0

                                    You need to elaborate your scheme then. Every time I’ve heard someone say “I hate capitalism and I have an alternative for it” what they really have is state capitalism (AKA communism in practice as opposed to the silly theory of communism written down somewhere).

                                    1. 0

                                      The universal means of production (automated labor), universally distributed.

                                      1. 0

                                        Who decides resource allocation?

                                        1. 0

                                          Who decides it now?

                                          1. 0

                                            The market

                                            1. 0

                                              How’s that workin’ out.

                                              1. 0

                                                Better than anything else people have tried.

                                                1. 0

                                                  Citation needed.

                                                  1. 0

                                                    Also, punch cards were better than anything that came before, and then we had better ideas that were enabled by advancing technology. It’s time we did the same for meeting basic human needs.

                                                    1. -1

                                                      You haven’t actually said what the replacement is for free markets and capitalism.

                                                      1. 0

                                                        Start with democratic socialism. End with technological post-scarcity.

                                                        1. 0

                                                          All countries with governments are socialist, not all are democratic, and not all have free markets. So that doesn’t add anything new.

                                                          Post-scarcity is another way of saying we have no plan on how to deal with resource contention, which is the hard problem

                              3. -1

                                it’s more and more immoral to couple the ability to get a job with the ability to stay alive and retain dignity.

                                What dignity is possible once you’re livestock to be taken care of?

                                The truth of the matter is there’s an ongoing demographic implosion. If they wait it out awhile, there won’t be that many people to have to have the universal income or whatever it is you’re arguing for.

                                1. 3

                                  You’re assuming that dignity and purpose are only possible under conditions of coerced labor. Your premise is false.

                                  I’m not arguing for UBI. I’m arguing for democratic access to the means of universal production (robotic labor, molecular nanotech, etc.), removing the need for things like “income”.

                            1. 1

                              I also hated the academic side when I attended, but one of the greatest benefits I got out of university was being in a little village with lots to do, everything accessible on foot, surrounded by friends. It’s a state of things that has a beautiful quaint aspect to it, especially when you consider how disparate our connections grow afterwards. If not for the high price tag, I might encourage people to go just for that experience. You can learn throughout your entire life, but it’s hard to find a similar social environment.

                              1. 1

                                Hah! Thanks for this review. I cracked up at a few points:

                                In the preface of the second edition it says that the first edition was reviewed “by a professional C programmer hired by the publisher.” That programmer said it should not be published. That programmer was right, but the publisher went ahead and published it anyway.

                                Also

                                If you browse search results for other books by Traister you’ll find a lot of questionable sounding titles: Making money with your microcomputer (1982), Leaping from BASIC to C++ (1994), […] Cave Exploring (1983)

                                😂

                                1. 1

                                  Cave Exploring sounds like it could be harmful to your health. Given Traister’s reputation in C programming.

                                1. 2

                                  This is the first time Heroku has ever been able to detect configuration options and block a deploy for a vulnerability like this.

                                  1. 1

                                    Is there a particular reason for it being a first? Also thanks for the write up and the fixes!

                                    1. 2

                                      Is there a particular reason for it being a first? Also thanks for the write up and the fixes!

                                      We’ve never had the capability before. I just added the code to detect configuration via rails runner recently https://github.com/heroku/heroku-buildpack-ruby/pull/758.

                                  1. 15

                                    As a junior developer doing my best to learn as much as I can, both technically and in terms of engineering maturity, I’d love to hear what some of the veterans here have found useful in their own careers for getting the most out of their jobs, projects, and time.

                                    Anything from specific techniques as in this post to general mindset and approach would be most welcome.

                                    1. 33

                                      Several essentials have made a disproportionate benefit on my career. In no order:

                                      • find a job with lots of flexibility and challenging work
                                      • find a job where your coworkers continuously improve themselves as much (or more) than you
                                      • start writing a monthly blog of things you learn and have strong opinions on
                                      • learn to be political (it’ll help you stay with good challenging work). Being political isn’t slimy, it is wise. Be confident in this.
                                      • read programming books/blogs and develop a strong philosophy
                                      • start a habit of programming to learn for 15 minutes a day, every day
                                      • come to terms with the fact that you will see a diminishing return on new programing skills, and an increasing return on “doing the correct/fastest thing” skills. (e.g. knowing what to work on, knowing what corners to cut, knowing how to communicate with business people so you only solve their problems and not just chase their imagined solutions, etc). Lean into this, and practice this skill as often as you can.

                                      These have had an immense effect on my abilities. They’ve helped me navigate away from burnout and cultivated a strong intrinsic motivation that has lasted over ten years.

                                      1. 5

                                        Thank you for these suggestions!

                                        Would you mind expanding on the ‘be political’ point? Do you mean to be involved in the ‘organizational politics’ where you work? Or in terms of advocating for your own advancement, ensuring that you properly get credit for what you work on, etc?

                                        1. 13

                                          Being political is all about everything that happens outside the editor. Working with people, “managing up”, figuring out the “real requirements’, those are all political.

                                          Being political is always ensuring you do one-on-ones, because employees who do them are more likely to get higher raises. It’s understanding that marketing is often reality, and you are your only marketing department.

                                          This doesn’t mean put anyone else down, but be your best you, and make sure decision makers know it.

                                          1. 12

                                            Basically, politics means having visibility in the company and making sure you’re managing your reputation and image.

                                            A few more random bits:

                                        2. 1

                                          start a habit of programming to learn for 15 minutes a day, every day

                                          Can you give an example? So many days I sit down after work or before in front of my computer. I want to do something, but my mind is like, “What should I program right now?”

                                          As you can probably guess nothing gets programmed. Sigh. I’m hopeless.

                                          1. 1

                                            Having a plan before you sit down is crucial. If you sit and putter, you’ll not actually improve, you’ll do what’s easy.

                                            I love courses and books. I also love picking a topic to research and writing about it.

                                            Some of my favorite courses:

                                            1. 1

                                              I’ve actually started SICP and even bought the hard copy a couple weeks ago. I’ve read the first chapter and started the problems. I’m on 1.11 at the moment. I also started the Stanford 193P course as something a bit easier and “fun” to keep variety.

                                        3. 14

                                          One thing that I’ve applied in my career is that saying, “never be the smartest person in the room.” When things get too easy/routine, I try to switch roles. I’ve been lucky enough to work at a small company that grew very big, so I had the opportunity to work on a variety of things; backend services, desktop clients, mobile clients, embedded libraries. I was very scared every time I asked, because I felt like I was in over my head. I guess change is always a bit scary. But every time, it put some fun back into my job, and I learned a lot from working with people with entirely different skill sets and expertise.

                                          1. 11

                                            I don’t have much experience either but to me the best choice that I felt in the last year was stop worrying about how good a programmer I was and focus on how to enjoy life.

                                            We have one life don’t let anxieties come into play, even if you intellectually think working more should help you.

                                            1. 8

                                              This isn’t exactly what you’re asking for, but, something to consider. Someone who knows how to code reasonably well and something else are more valuable than someone who just codes. You become less interchangeable, and therefore less replaceable. There’s tons of work that people who purely code don’t want to do, but find very valuable. For me, that’s documentation. I got my current job because people love having docs, but hate writing docs. I’ve never found myself without multiple options every time I’ve ever looked for work. I know someone else who did this, but it was “be fluent In Japanese.” Japanese companies love people who are bilingual with English. It made his resume stand out.

                                              1. 1

                                                . I got my current job because people love having docs, but hate writing docs.

                                                Your greatest skill in my eyes is how you interact with people online as a community lead. You have a great style for it. Docs are certainly important, too. I’d have guessed they hired you for the first set of skills rather than docs, though. So, that’s a surprise for me. Did you use one to pivot into the other or what?

                                                1. 7

                                                  Thanks. It’s been a long road; I used to be a pretty major asshole to be honest.

                                                  My job description is 100% docs. The community stuff is just a thing I do. It’s not a part of my deliverables at all. I’ve just been commenting on the internet for a very long time; I had a five digit slashdot ID, etc etc. Writing comments on tech-oriented forums is just a part of who I am at this point.

                                                  1. 2

                                                    Wow. Double unexpected. Thanks for the details. :)

                                              2. 7

                                                Four things:

                                                1. People will remember you for your big projects (whether successful or not) as well as tiny projects that scratch an itch. Make room for the tiny fixes that are bothering everyone; the resulting lift in mood will energize the whole team. I once had a very senior engineer tell me my entire business trip to Paris was worth it because I made a one-line git fix to a CI system that was bothering the team out there. A cron job I wrote in an afternoon at an internship ended up dwarfing my ‘real’ project in terms of usefulness to the company and won me extra contract work after the internship ended.

                                                2. Pay attention to the people who are effective at ‘leaving their work at work.’ The people best able to handle the persistent, creeping stress of knowledge work are the ones who transform as soon as the workday is done. It’s helpful to see this in person, especially seeing a deeply frustrated person stand up and cheerfully go “okay! That’ll have to wait for tomorrow.” Trust that your subconscious will take care of any lingering hard problems, and learn to be okay leaving a work in progress to enjoy yourself.

                                                3. Having a variety of backgrounds is extremely useful for an engineering team. I studied electrical engineering in college and the resulting knowledge of probability and signal processing helped me in environments where the rest of the team had a more traditional CS background. This applies to backgrounds in fields outside engineering as well: art, history, literature, etc will give you different perspectives and abilities that you can use to your advantage. I once saw a presentation about using art critique principles to guide your code reviews. Inspiration can come from anywhere; the more viewpoints you have in your toolbelt the better.

                                                4. Learn about the concept of the ‘asshole filter’ (safe for work). In a nutshell, if you give people who violate your boundaries special treatment (e.g. a coworker who texts you on your vacation to fix a noncritical problem gets their problem fixed) then you are training people to violate your boundaries. You need to make sure that people who do things ‘the right way’ (in this case, waiting for when you get back or finding someone else to fix it) get priority, so that over time people you train people to respect you and your boundaries.

                                                1. 3

                                                  I once saw a presentation about using art critique principles to guide your code reviews. Inspiration can come from anywhere; the more viewpoints you have in your toolbelt the better.

                                                  The methodology from that talk is here: http://codecrit.com/methodology.html

                                                  I would change “If the code doesn’t work, we shouldn’t be reviewing it”. There is a place for code review of not-done work, of the form “this is the direction I’m starting to go in…what do you think”. This can save a lot of wasted effort.

                                                2. 3

                                                  The biggest mistake I see junior (and senior) developers make is key mashing. Slow down, understand a problem, untangle the dependent systems, and don’t just guess at what the problem is. Read the code, understand it. Read the code of the underlying systems that you’re interacting with, and understand it. Only then, make an attempt at fixing the bug.

                                                  Stabs in the dark are easy. They may even work around problems. But clean, correct, and easy to understand fixes require understanding.

                                                  1. 3

                                                    Another thing that helps is the willingness to dig into something you’re obsessed with even if it is deemed not super important by everyone around you. eg. if you find a library / language / project you find fun and seem to get obsessed with, that’s great, keep going at it and don’t let the existential “should i be here” or other “is everyone around me doing this too / recommending this” questions slow you down. You’ll probably get on some interesting adventures.

                                                    1. 3

                                                      Never pass up a chance to be social with your team/other coworkers. Those relationships you build can benefit you as much as your work output.

                                                      (This doesn’t mean you compromise your values in any way, of course. But the social element is vitally important!)

                                                    1. 7

                                                      Deno seems very interesting. He’s trying to rectify his mistakes and adopt typed, async JS.

                                                      URL imports seem somewhat interesting but have one large flaw in my opinion - they drop the singular responsibility of security in exchange for a shared one.

                                                      NPM has a lot of issues, especially security ones, but at least it’s an actively maintained, up to date entity. If something goes wrong someone will notice very quickly and they will attempt to rectify it very quickly.

                                                      With URL imports, however, I’m worried that we’ll lose the quickly part of this. Imagine a scenario in which an early adopter makes a left-pad like module - something trivial that isn’t in the STL but everyone wants. In a few years they migrate away, and become removed from the tech community (but still host their domain/js)

                                                      If this domain gets compromised, every package with that import will be done. There won’t be a central authority that can sink that package or domain - it will be a shared responsibility of every developer, which is significantly more dangerous than the singular responsibility of npm.

                                                      1. 14

                                                        I was amused to note that he cautions against using “cute” code and then goes on to call URL imports cute at around 21:14

                                                        1. 4

                                                          The main thing I’d counter with is that the web has run on URL imports like that, and has managed it fairly well. Spread of imports also means spread of attack targets. NPM is a singular target by comparison, vs the various CDNs, libraries copied locally, and so on that this scheme proposes.

                                                          Overall, it’s a different tradeoff, and so far, this JS runtime is a thought experiment.

                                                        1. 2

                                                          How much Nim should one know in order to be able to maintain an instance? I tried setting up a Discourse server and found it somewhat onerous - even knowing JS and Rails.

                                                          1. 1

                                                            There should be no knowledge necessary. If you want some advanced customisation of the produced HTML then you may need to dive into the code, but otherwise my aim is to just give you two executables, one for the backend and one for the initial set up.

                                                            My main priority so far was to get forum.nim-lang.org up and running. I also wanted to gauge interest to see if people would actually like to use this instead of Discourse. My objective in the long run is to provide release tarballs to spare the trouble of installing the whole Nim ecosystem. If there is interest I will certainly do that.

                                                          1. 18

                                                            Definitely way complicated. Nomad(https://nomadproject.io/) is what we chose, because it is so operationally simple. You can wrap your head around it easily.

                                                            1. 7

                                                              I haven’t used either in production yet, but isn’t the use case of nomad much more restricted then kubernetes? It’s only the scheduling part and leaves it to the use define, for example, ingress through a load balancer and so on?

                                                              1. 10

                                                                Yes, Load balancing is your problem. Nomad is ONLY a task scheduler across a cluster of machines. Which is why it’s not rocket science.

                                                                You say I need X cpu and X memory and I need these files out on disk(or this docker image) and run this command.

                                                                It will enforce your task gets exactly X memory, X cpu and X disk, so you can’t over-provision at the task level.

                                                                It handles batch(i.e. cron) and spark workloads, system jobs(run on every node) and services (any long-running task). For instance with nomad batch jobs you can almost entirely replace Celery and other distributed task queues, in a platform and language agnostic way!

                                                                I’m not sure I’d say the use-case is much more restricted, since you can do load balancing and all the other things k8s does, but you use specialized tools for these things:

                                                                • For HTTPS traffic you can use Fabio, Traefik, HAProxy, Nginx, etc.
                                                                • For TCP traffic you can use Fabio, Relayd, etc.

                                                                These are outside of Nomad’s scope, except that you can run those jobs inside of Nomad just fine.

                                                                edit: and it’s all declarative, a total win.

                                                                1. 1

                                                                  Why not haproxy for tcp too?

                                                                  1. 1

                                                                    I don’t actually use HAProxy, so I can’t really comment on if it does TCP as well, if it does, AWESOME. I was definitely not trying to be limiting, hence the etc. at the end of both of those.

                                                                    We use Nginx and Relayd.

                                                                    1. 2

                                                                      It does TCP. See the reliability and security sections of the web site to see why you might want it.

                                                                      1. 2

                                                                        Thanks!

                                                              2. 4

                                                                Oooh, the fact that it’s by HashiCorp is a good sign. I’ll have to read up on this. Thanks!

                                                              1. 5

                                                                Some extra details from the linked bug report and commit:

                                                                • What about triple-dot ranges that exclude the end value? The bug report said “I don’t think ary[1...] (exclusive) is meaningful.” Despite this, I see from the commit that endless ranges with triple-dot were implemented. There is only one test case that uses the range in a way other than inspecting its attributes, and that test shows that a 3...nil range iterates over the same numbers as a 3..nil range when passed to Array#fill.

                                                                • What about infinite ranges in the other direction, (..0) and (nil..0)? They could theoretically be used for checking if a number is less than 100, for example. Well, they are not part of this feature because it would be too hard to implement in Ruby’s grammar:

                                                                  It is better to have ary[..1] as a consistency. But it will cause a shift/reduce conflict. Anyway, ary[0..1] looks not so bad to me since it have no cursed negative index. So I don’t push it.

                                                                1. 2

                                                                  Couldn’t you apply a unary minus to the infinite range and get the same thing? Or am I missing something?

                                                                  1. 1

                                                                    Good point, I hadn’t even thought of the negative infinity case.

                                                                  1. 1

                                                                    Interesting. I wonder if this is in response to a flood of new programmers from bootcamps, or perhaps non-technical users? It could very well be just a new learning tool, as well, but it seems like a fairly simple webapp to use for most established developers.

                                                                    1. 8

                                                                      The imperative and declarative versions are, in two cases, semantically different.

                                                                      Execute something on every element with map: the for-loop doesn’t do anything with the return value from performSomething, whereas map puts the results into an array. Consider using forEach instead of map. e.g. array.forEach(performSomething)

                                                                      Finding a single element in the array: the use of a return in the for-loop causes an early exit, whereas filter will iterate through the entire array.

                                                                      Iterate over an array to count a property of each item: I can only nit-pick and say the declarative implementation as-written is more verbose than the imperative one. Please consider: items.reduce((result, item) => result + item.content.value, 0)

                                                                      1. 3

                                                                        Finding a single element in the array: the use of a return in the for-loop causes an early exit, whereas filter will iterate through the entire array.

                                                                        There’s also Array.prototype.find().

                                                                        With regards to this improvement:

                                                                        items.reduce((result, item) => result + item.content.value, 0)

                                                                        If you want to get (probably too) fancy with destructuring, you could do:

                                                                        items.reduce((result, { content: { value } }) => result + value, 0)

                                                                        1. 1

                                                                          items.reduce((result, { content: { value } }) => result + value, 0)

                                                                          That’s clever, thanks I will include this example!

                                                                          1. 1

                                                                            There’s also Array.prototype.find().

                                                                            Is Array.prototype.find() ES5?

                                                                            1. 1

                                                                              I’m still not sure what aligns to ES5 or ES6, but as per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find:

                                                                              This method has been added to the ECMAScript 2015 specification and may not be available in all JavaScript implementations yet.

                                                                              1. 2

                                                                                ES6 and ES2015 are two names for the same thing. ES5 would be ES2009 under the new naming scheme.

                                                                          2. 1

                                                                            Good points, thanks for the feedback, I’m editing the post to incorporate it

                                                                          1. 2

                                                                            Just a note, it would be helpful to preface code samples with the language that they’re written in (in this case, Go). Thanks!

                                                                            1. 1

                                                                              Good point. I’ll update the post.

                                                                            1. 5

                                                                              Another “quirks” question: did you find any unexpected quirks of Go that made writing this emulator harder or easier?

                                                                              1. 5

                                                                                In this particular case, it feels like the code isn’t too far from what C code would be: here are some basic data structures and here are some functions that operate on them, mostly on the bit level. No fancy concurrency models nor exciting constructs. I think given the fact that this is an inherently low level program, most nicieties from Go weren’t immediately needed.

                                                                                I did use some inner functions/closures and hash maps, but could’ve just as well done without them. The bottom line is that the language didn’t get in the way, but I didn’t feel like it was enourmously helpful, other than making it easier to declare dependencies and handling the build process for me.

                                                                                1. 4

                                                                                  Did you run into any issues with gc pauses? That’s one of the things people worry about building latency sensitive applications in go.

                                                                                  1. 3

                                                                                    Not the OP, but I would assume this kind of application generates very little garbage in normal operation.

                                                                                    1. 2

                                                                                      The gc pauses are so miniscule now, for the latest releases of Go, that there should be no latency issues even for realtime use. And it’s always possible to allocate a blob of memory at the start of the program and just use that, to avoid gc in the first place.

                                                                                      1. 2

                                                                                        The garbage collector hasn’t been an issue either. Out of the box, I had to add artificial delays to slow things down and maintain the frame rate, so I haven’t done much performance tuning/profiling. I am interested in scenarios where this would be critical though.

                                                                                        1. 1

                                                                                          Go’s GC pauses are sub-millisecond so it’s not an issue.

                                                                                      2. 3

                                                                                        Interested in this as well. I’ve toying with the idea of writing a CHIP-8 emulator in Go and would love to hear about how is the experience of writing emulators.

                                                                                        1. 3

                                                                                          I did exactly this as a project to learn Go! I used channels in order to control the clock speed and the timer frequency and it ended up being a really nice solution. The only real hangup I had was fighting with the compiler with respect to types and casting, but having type checking overall was a good thing.

                                                                                        1. 2

                                                                                          I love how reddit is the new Digg and HN is the new slashdot at the top left XD

                                                                                          Can’t seem to get gifs to work in my sig, though T_T is it just [img]?

                                                                                          1. 3

                                                                                            You need the ! before a link to turn it into an image.

                                                                                            edit: Contrary to what it says, it’s NOT BBCode, but rather this newfangled “markdown” some Mac nerd invented. I bet it won’t catch on, it’s not HTML-like enough.

                                                                                            1. 2

                                                                                              Thanks!

                                                                                              Oh wow, that gif is obnoxiously huge. Hell yeah.

                                                                                              EDIT - I changed my mind, too much

                                                                                          1. 8

                                                                                            “Not only that, any code examples in rustdoc are treated like tests and get executed during compilation!”

                                                                                            This is brilliant. First time I’ve heard of it. ZeD on Hacker News said Python can do it, too, with seangransee offering this example.

                                                                                            Aside from a good idea, it looks like it should also be a new requirement for high-assurance systems where all examples of system usage are executable. It’s often implicit where you’re already supposed to have both tests of all functions and consistency with documentation. At the least, it could be an extra check on these.

                                                                                            1. 14

                                                                                              I’m over the moon about doctests. Elixir has them too, that’s where I saw the light. In the past, I’ve gone to annoying lengths to ensure that code examples in documentation don’t go stale; it’s a great feeling to have first-class support for that workflow.

                                                                                              1. 2

                                                                                                I’ve found that in Elixir having both doctests and normal tests is quite handy–one as a quick sanity check and a way of demonstrating an API, and the other as a full way of confirming behavior. The use of tags to turn on and off different sets of tests is also not well supported (to my knowledge) with doctests.

                                                                                                1. 3

                                                                                                  AFAIK turning Elixir doctests on and off is not supported. That bothers me just a bit, because there are times when I’d like to show some non-testable code (e.g., demonstrating a request to an external network service) in the exact same syntax that my doctests use (iex>, etc).

                                                                                              2. 5

                                                                                                I think the first place I saw that was R, where it’s used pervasively in the package repository (CRAN). In fact the output of example REPL sessions is generated by running the code, so besides being used as tests that are flagged if they fail to run entirely, it also keeps the examples up to date with minor changes to output format, etc., which can otherwise get out of date even when the code continues to work.

                                                                                                1. 4
                                                                                                  1. 4

                                                                                                    I’ve found that in practice I write far fewer testable Go examples than I do in Rust code. In Rust, I just drop into Markdown, write the code, and I’m done. It’s incredibly low friction.

                                                                                                  2. 2

                                                                                                    D achieves the same the other way round. Instead of treating documentation like code, D has unit test code blocks and can treat them as documentation. This makes it easier for the tooling, since syntax highlighting etc applies to the unit tests as well.

                                                                                                    This is not a really critical difference, but if you design a new language, I would suggest the D approach as slightly better.

                                                                                                    1. 2

                                                                                                      I’ve generated documentation from tests before (in Ruby’s rspec). Just thinking about it, isn’t D’s approach prone to the same weakness as the comments that they use to generate the docs? That is, when you use comments or non-executable code (in my case it was string descriptors) to generate docs, they can get out of date with the actual code, whereas if you write tests inside documentation, the docs may grow stale but the tests will break.

                                                                                                  1. 6

                                                                                                    Just a note: I found the term Model-Based Testing a bit distracting - then again, I come from a Rails background. I think “Generative Testing in Rust with QuickCheck” would have been more helpful with no prior knowledge of QuickCheck.

                                                                                                    This also set me off into exploring QuickCheck. For those who don’t know, the most helpful thing I saw to help understand it was watching this video that showed off test.check, a QuickCheck implementation in Clojure: https://www.youtube.com/watch?v=u0TkAw8QqrQ

                                                                                                    Basically, it’s a way to generate random data and data structures (within certain bounds that you define) to be used as inputs in testing your application logic. Since I was also confused about this, it seems like people run QuickCheck as a step separate from their non-generative specs to identify specific edge cases and then add those edgecases as regression tests to their overall test suite. In some generative testing libraries I saw after poking around, they’re even run as part of the test suite, though I’m not sure how I feel about that - couldn’t that result in missing a case locally that then fails on CI due to different inputs?

                                                                                                    1. 5

                                                                                                      In the past, it was called specification-based (QuickCheck paper said “specifications”), model-based, or contract-based… test generation depending on which crowd you were listening to. Recently, most posts call it property-based testing. All are accurate given they’re technically true and have prior work. The superset would probably be specification-based since what they use in each is a specification. Formal specifications are also oldest technique of them.

                                                                                                      Generative is ambiguous since it sounds like it just means automated. All the test generators are automated to some degree. So, we name them from where the process starts. Far as what name, even I started using property-based testing instead of specification-based testing as default to go with the flow. I still use others if the discussion is already using those words, though. For instance, I might say…

                                                                                                      1. Spec-based if we’re talking formal specifications

                                                                                                      2. Model-based if we’re talking Alloy models.

                                                                                                      3. Contract-based if we’re talking Design-by-Contract, Eiffel, or Ada/SPARK since that’s their language.

                                                                                                      4. Property-based if talking to people using popular languages or something since they’ll find helpful stuff if they Google with that.

                                                                                                      1. 2

                                                                                                        Thanks for the background information!

                                                                                                      2. 2

                                                                                                        There’s also been some work done to save failing inputs for later retest. I’ve used that to do test driven development with properties.

                                                                                                        I know that’s supported in version 2 of the original quick check, almost certain Python’s hypothesis supports that, not sure about others.

                                                                                                        1. 2

                                                                                                          If you have a QuickCheck implementation that permits easy testing of a concrete test case, grab it and use it. Once upon a time, QC found a bug. Keep that concrete test case and add it to your regression test suite. Randomized testing means that you don’t really know when randomness will create that same concrete test case again. But if your regression suite includes the concrete test case, you are assured that your regression suite will always check that scenario.

                                                                                                          In the Erlang QuickCheck implementations (the commercial version from Quviq AB in Sweden and also the open “PropEr” package), there’s a subtlety in saving a concrete test case. I assume it’s the same feature/problem with Rust’s implementation of QC. The problem is: re-executing the test assumes that the test model doesn’t change. If you’re actively developing & changing the QC model today, then you may unwittingly change the behavior of re-executing a concrete test that was added to your regression test suite last year. If you’re aware of that feature/problem, then you can change your process/documentation/etc to cope with it.

                                                                                                          1. 2

                                                                                                            That’s probably because the first prototype for this required the random value as input to the value generator. I know that because I wrote it, and pushed for its inclusion in the second version of QuickCheck.

                                                                                                            Nowadays there are libraries that will generate the actual value in such a way that you can copy and paste into a source file.

                                                                                                            I’ve heard that hypothesis in Python keeps a database of failed inputs, not sure if anything else has that feature.

                                                                                                            1. 2

                                                                                                              Randomness is only one place where things can go wrong with saved concrete test cases.

                                                                                                              For example (not a very realistic one), let’s extend the Rust example of testing a tree data structure. The failing concrete test case was: ([Insert(0, 192), Insert(0, 200), Get(0)])

                                                                                                              Let’s now assume that X months later, the Insert behavior of the tree changes so that existing keys will not be replaced. (Perhaps a new operation, Replace, was added.) It’s very likely that re-execution of our 3-step regression test case will fail. A slightly different failure would happen if yesterday’s Insert were removed from the API and replaced by InsertNew and Replace operations. I’m probably preaching to the choir, but … software drifts, and testing (in any form) needs to drift with it.

                                                                                                              1. 1

                                                                                                                That’s an excellent point, I have no idea how to automate that. You’d have to somehow notice that the semantics changed and flush all the saved test inputs, sounds like more work than gain.

                                                                                                                This is great info, any other thoughts on how saved inputs could go wrong?

                                                                                                                1. 2

                                                                                                                  Ouch, sorry I didn’t see your reply over the weekend. I can’t think of other, significantly different problems. I guess I’d merely add a caution that “semantics changed” drift between app/library code & test code isn’t the only type of drift to worry about.

                                                                                                                  If you change the implementation, and the property test is validating a property of the implementation, you have more opportunity for drift. For example, checking at the end of a test case. For example, for testing a hash table when deleting all elements, “all buckets in the hash have lists of length zero” could be a desirable property. The test actually peeks into the hash table data structure and checks all the buckets and their lists. The original implementation had a fixed number of buckets; a later version has a variable number of buckets. Some bit of test code may or may not actually be examining all possible buckets.

                                                                                                                  It’s a contrived example, one that doesn’t apply only to historical, failing test cases. But the best that I can think at the moment. ^_^

                                                                                                                  -Scott

                                                                                                        2. 1

                                                                                                          In some generative testing libraries I saw after poking around, they’re even run as part of the test suite, though I’m not sure how I feel about that - couldn’t that result in missing a case locally that then fails on CI due to different inputs?

                                                                                                          This is a potential problem with property-based testing, but to turn the question around - if you’re writing unit tests by hand, how do you know you didn’t miss a case?

                                                                                                          That’s why you use them together.

                                                                                                          1. 2

                                                                                                            I understand using property-based testing to find edge cases, but including it in the test suite seems to introduce a lot of uncertainty as to whether your build will succeed? And potentially how much time it will take to run the tests. Granted, finding edge cases is important regardless of when you find them, I’d just be more comfortable running the property-based tests as a separate step, though I’d be happy to be convinced otherwise.

                                                                                                            1. 1

                                                                                                              Correct me if I’m misunderstanding you. If the testing is part of build cycle, a build failure will likely indicate the software didn’t work as intended. You’ll also have a report waiting for you on what to fix. If it’s taking too much time, you can put a limit on how much time is spent per module, per project, or globally on test generation during a build. For instance, it’s common for folks using provers like SPARK Ada’s or model-checkers for C language to put a limit of 1-2 min per file so drawback of those tools (potentially unlimited runtime) doesn’t hold the work up. Also, if it takes lots of running time to verify their code, maybe they need to change their code or tooling to fix that.

                                                                                                              1. 2

                                                                                                                No, I think your understanding is correct, and that’s definitely part of the point of running specs in the build process. I guess I’m just operating from advice I got early on to keep specs as deterministic as possible. I don’t remember where I got this advice, but here’s a blog post: https://martinfowler.com/articles/nonDeterminism.html

                                                                                                                He also recommends this, which is what I would instinctively want to do with property-based testing:

                                                                                                                If you have non-deterministic tests keep them in a different test suite to your healthy tests.

                                                                                                                Though the nondeterministic tests Fowler is talking about seem to be nondeterministic for different reasons than one would encounter when setting out to do property-based testing:

                                                                                                                • Lack of Isolation
                                                                                                                • Asynchronous Behavior
                                                                                                                • Remote Services
                                                                                                                • Time
                                                                                                                1. 2

                                                                                                                  Just going by the problem in his intro, I remember that many people use property-based testing as a separate pass from regression tests with some failures in PBT becoming new, regression tests. The regression tests themselves are static. I’d guess they were run before PBT, as well, with logic being one should knock out obvious, quick-to-test problems before running methods that spend lots of time looking for non-obvious problems. Again, I’m just guessing they’d do it in that order since I don’t know people’s setups. It’s what I’d do.

                                                                                                                  1. 2

                                                                                                                    Ah, okay, so separating regression tests from PBT does seem to be a common thing.

                                                                                                        1. 2

                                                                                                          Considering the pros of defer, there seems to be very little usage for async.

                                                                                                          if you specify both, async takes precedence on modern browsers, while older browsers that support defer but not async will fallback to defer.

                                                                                                          So why would you use async at all? And why do newer browsers even bother to support it?

                                                                                                          1. 7

                                                                                                            There are some (admittedly edge case) scenarios where async is still desirable. For example on the BBC News homepage if we loaded our scripts with defer, a bunch of non-defer third-party scripts would execute first and make the page feel slow. We used async instead, so that parsing isn’t blocked while the script is being fetched but it is blocked once the script is available so we can enhance the page and make it feel complete without having to wait for other scripts to execute first.

                                                                                                            1. 2

                                                                                                              Thanks for writing this, I found very little information online on when to use async is a better choice, I added a bit more information to consider this scenario 👍🏼