Convert HTML to PDF, an OpenSource Alternative Based on Webkit - <AUTHOR> http://beebole.com/en/blog/general/convert-html-to-pdf-with-full-css-support-an-opensource-alternative-based-on-webkit/

<comment><USER2> With extensive experience with both print and web all I can say is:

HTML and PDF were designed for two entirely different things, PDF being much more strict in this respect (as it can make assumptions about display medium that HTML cannot).

Thinking you can go from HTML to PDF with correct results is a very wrong assumption.

<comment><USER3> Agreed for arbitrary HTML, but there a lot of webapps (including one I've written) where it's useful to be able to produce PDF output. When you control the HTML and can test that it converts to PDF the way you want, this can be much faster than trying to generate PDFs from raw Postscript or whatever.

<comment><USER4> Exactly. This has countless applications. Vastly simpler to create an HTML report, and convert to PDF, than to program said report in some sort of PDF library. You can use your framework's template library, and leverage existing skills. Your designers can design reports as easily as pages.

On my Mac, the kerning was wacked on Arial. Probably something that can be done about that. But all in all - highly impressive.

<comment><USER5> I found that the font rendering with this was a little weird in general. Arial was pretty horrible, other fonts were a bit better but letter spacing was still always a bit off (this was on a PC btw, so it's not just Mac). I was never able to figure out what was going on, so we ended up going with a for- pay html-to-pdf library because it didn't have the same font rendering issues.

</comment></comment></comment></comment><comment><USER6> You can also use CutyCapt to capture web screenshots to PNG, SVG, PDF, etc.</comment>


Ask HN: Password update/distribution mechanisms for IoT? - <AUTHOR>

Are there any standard approaches for password management in the IoT world? In the web world, the pattern is well defined. Reset your forgotten password, send an email with a temp, login with it, and change password more permanently.
IoT companies have the same challenge PLUS distributing passwords from your webservice down to your device/hub (well, that's one model). So far, googling has shown me that IoT doesn't really have this solved in a standard way but maybe I am not doing a good job with keywords or something.
We have contemplated various approaches but most of them have a viable attack vector. If the window of that vector is skinny enough it might be ok, but it seems like this problem is going to turn into a security or a management nightmare.
Ideas, suggestions, examples? <comment><USER2> Devices should not store passwords (or password hashes), and so should never need updating.

Instead, a unique TLS client certificate should be issued to the device during provisioning. If a device gets compromised, revoke its cert without affecting all the other (uncompromised) devices belonging to the user.

Getting through that provisioning process without confusing or annoying the user is the hard part.</comment>


Aphex Twin Speaks to Tatsuya Takahashi (2017) - <AUTHOR> http://item.warp.net/interview/aphex-twin-speaks-to-tatsuya-takahashi/ <comment><USER2> This isn't just any old ex-Korg engineer; Tatsuya Takahashi is arguably the most influential living synth designer.

[https://www.npr.org/sections/therecord/2017/12/22/569092364/...](https://www.npr.org/sections/therecord/2017/12/22/569092364/analog- for-the-people-synth-master-tatsuya-takahashi-on-engineering-fun)

<comment><AUTHOR> I didn't realize how big Takahashi was. Thanks for the article!

</comment></comment><comment><USER3> RDJ drops a link at the end of the article.

If you've ever studied phonetics, you need to check this out:

[https://dood.al/pinktrombone/](https://dood.al/pinktrombone/)

<comment><USER4> That is super cool!

With some clever keyboard controls perhaps one could learn to actually "talk" with it?

<comment><USER5> Google the 'Voder'. A speech synthisis keyboard from 1939 using the concept you describe. There are some great demo videos of it.

<comment><USER6> Voder (1939)

[https://www.youtube.com/watch?v=TsdOej_nC1M](https://www.youtube.com/watch?v=TsdOej_nC1M)

IBM 7094 singing Daisy Bell (1961)

[https://www.youtube.com/watch?v=41U78QP8nBk](https://www.youtube.com/watch?v=41U78QP8nBk)

</comment></comment></comment></comment><comment> 8f2ab37a-ed6c I'm obviously a few decades late to the party, but I've been obsessed with analog hardware synths for a few years now.

There's something magical about messing around with a sequencer/arpeggiator, mixing together a couple of VCOs, changing their wave type, detuning them, modulating filters, amplitudes, rhythms. The sonic options are staggering, you can sit there all day turning knobs and stumbling upon interesting and quirky ideas.

Part of me thinks that "it's all been done before", yet there's joy to you doing this yourself from scratch, even if you're not the pioneer.

<comment><USER7> Take heart! All culture, and especially music, is about retracing steps. "Pioneering" in music is about capturing the Zeitgeist in just the right manner and with extraordinary expertise to be undeniable, which then creates a new normal. That's not exactly pioneering, it's standard setting. The perfection of a musical meme is retroactively confirmed by virtue of its proliferation. It's genius, while undeniable, as a strong relationship with luck.

</comment></comment><comment><AUTHOR> I'm stoked to see that others are interested in the article!

The important bit for me is Richard D. James's interest in promoting microtonal music, and that Tatsuya and Korg were cool enough to implement it in a relatively cheap synth.

Microtonal music is a vast landscape that I feel has so much left to uncover. I hope that tools like Korg's *logue line of synths will get new folks interested in breaking out of the limits of 12 tone equal temperament.

<comment><USER8> It is sad how pop music on a Western model with its 12-tone equal temperament (or an East Asian model with pentatonic equal temperament) has, in the course of invading the whole world, gradually marginalized many local traditions that are microtonal. If those local traditions cannot manage to recover on their own, maybe some openness to microtones among Western pop music would help non- Western microtonal musics get more of the limelight.

Unfortunately, as with the highly complex rhythms that RDJ employed in some of his work (e.g. the "drill-and-bass" style), microtones are likely to entertain only a relatively small demographic of anoraks while striking the mainstream as too "weird".

<comment><USER9> One of my biggest disappointments traveling around Asia is that Western pop music is totally ubiquitous here and contemporary Asian pop music sounds just like it. There's something profoundly depressing about hearing Maroon 5 playing in a little bar in Cambodia.

</comment></comment></comment><comment><USER10> I thought I had seen this article before. The discussion is much more lively this time around, but for reference here is a previous HN post from 2017:

[https://news.ycombinator.com/item?id=14771533](https://news.ycombinator.com/item?id=14771533)

</comment><comment><USER11> Takahashi at the Granular Convolver Lecture (Berlin 2018).Discusses convolution & SuperCollider.

[https://www.youtube.com/watch?v=dMXpJY2ilIs](https://www.youtube.com/watch?v=dMXpJY2ilIs)

Article with more info: [https://daily.redbullmusicacademy.com/2018/09/the- granular-c...](https://daily.redbullmusicacademy.com/2018/09/the-granular- convolver)

</comment><comment><USER12> Great read, although I feel Like RDJ is being funny and intentionally sounding like an infomercial.

I guess he did work on it enough to want to see some units move.

</comment><comment><USER13> I've heard a few of Aphex's stuff. How is he live? Perhaps I'm not musically apt to fully get it, but I would like to.

<comment><USER14> To be honest, I think he is more of a musician's musician and a bit hard to "get".

Outside the artistic creativity itself, I find his music more enjoyable by recognizing the craftsmanship and musicianship required to create his unique sounds and rhythms. Once you realize it's not just random noises, perhaps some of the songs may speak to you like I found.

If you have ever tried creating electronic music with drum machines, synthesizers, midi loopers, etc, it would be a lot easier to appreciate his music I think.

Maybe similar to say, free jazz? If you don't appreciate or understand the nuances, I doubt you'd enjoy listening to it.

I'm on mobile or I'd research, but I'm sure there are some great videos on YouTube explaining some of his or similar techniques?

<comment><USER15> I'm not a musician, but I love `Selected Ambient Works 85–92`. It sounds way ahead of its time.

<comment><USER16> Best EDM album ever, I'd say.

<comment><USER17> EDM isn't a catch all term for all electronic music

<comment><USER18> Yeah he's IDM not EDM, IDM is a older term from the 90s they called it "intelligent dance music" because it uses the tools of dance music but just like you could dance to Duke Ellington but nobody danced to Charlie Parker you can't exactly dance to music as complex as his but it enjoyable listening for sure.

<comment><USER19> > Yeah he's IDM not EDM, IDM is a older term from the 90s they called it > "intelligent dance music"

AKA "beard stroking music" in the D&B world.

It's music that doesn't energize people and get them on the dance floor. Go see a IDM/"experimental/"beard stroking" DJ live, all you see are a bunch of young male hipsters standing around stroking their beards, commenting on the uniqueness of the "interplay".

<comment><USER10> Sounds very similar to the reasoning behind the "shoegaze" genre name. All of the above of which I'm a big fan! Guess I like heady music, more recently have seen IDM described as braindance as well.

<comment><USER19> The etymology seems to be the same, but I've also heard people classify Deftones as "shoegaze", which makes zero sense to me.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER20> Anyone know what keyboard he's talking about here? An omnichord? That's all I can think of, but it doesn't have an actual string...

"RDJ: I've got one Japanese keyboard, Suzuki, which has got some Japanese tunings built in and a little string on one end that you can plucK"

<comment><USER21> [https://www.matrixsynth.com/2018/07/suzuki-waraku-iii- super-...](https://www.matrixsynth.com/2018/07/suzuki-waraku-iii-super- japanese-koto.html)

</comment></comment><comment><USER22> For more information on microtuning and MIDI

[https://en.xen.wiki/w/List_of_Microtonal_Software_Plugins](https://en.xen.wiki/w/List_of_Microtonal_Software_Plugins)

</comment><comment><USER23> If anyone is looking for an accessible Aphex Twin track, I would give "Alberto Balsalm" a try. One of my favourites on my University radio show. (That no one listened to back in the early 2000s. :)

<comment><USER24> They use the very early Aphex Twin works on TV as background/intro music. Millions get 'ambiently' subjected to what started out as far from 'accessible', i.e. 1000 white label pressings on his original label Rabbit Recordings.

I am impressed that Warp are still going, there is and was something magical about seeing that logo majestically spin round at 33 rpm. In the days before the Internet you only found Warp records in independent record shops, the High Street majors were hiding the good stuff from you. Plus the BBC banned dance music back then. You had to be a true 'raver' and into the music to hear Aphex Twin, it slotted in to the 'chill out' part of the scene.

This is why I find it so funny when I hear a little bit of Aphex Twin, Autechre or other Warp stablemates such as Sabres of Paradise as the backing track to a BBC documentary about serious stuff.

Imaginably anything is 'accessible' given enough time. The audience are always playing catch up with an innovative artist.

<comment><USER25> "In the days before the Internet you only found Warp records in independent record shops" ? Are you sure about that? That's not really true in the UK, both HMV and Virgin stocked early Aphex, and I think my Selected Ambient Works came from Our Price of all places on week of release. You couldn't get more mainstream where I lived.

I wouldn't say the Beeb banned dance music, either. I first heard LFO's LFO on radio one, which is synonymous with WARP.

As for Sabres - Screamadelica won the Mercury music prize with Weatherall in charge. It's not like they were off the radar or anything.

Autechre started out quite normal, but have morphed into probably the most complex out of everything that you've mentioned. They're well-known, but their music is anything but mainstream today - it's a running joke that they used to make music :)

<comment><USER26> Indeed The John Peel Show was awash with the stuff in the early 90s, certainly where I heard LFO, Aphex Twin (etc) for first time.

</comment></comment></comment></comment><comment><USER27> Noob here. If anyone could translate as to what technique they're talking about for circumventing the lack of velocity on Volca fm, it'd be super nice.

<comment><USER27> So apparently, "motion sequence" is Korg's term for automation—i.e. you fiddle the velocity slider while playing back a loop instead of putting the velocity in when playing the keys initially.

</comment></comment><comment><USER28> Seen him live in Leeds in 1998. Sat in the cubicle he vacated when he left the place at a Rephlex gig he didn't play at in 2001 (At the Leeds Brudenell Social Club). And I played live at the same venue as a previous Rephlex gig in Edinburgh (the University) in 2001.</comment>


Principles for C programming - <AUTHOR> https://drewdevault.com/2017/03/15/How-I-learned-to-stop-worrying-and-love-C.html <comment><USER2> _Avoid magic. Do not use macros._

Disagree. Use magic, especially macros, _in ways such that your code becomes easier, not harder, to understand_.

A few examples from my own code:

1\. My "elastic arrays" ([https://github.com/Tarsnap/libcperciva/blob/master/datastruc...](https://github.com/Tarsnap/libcperciva/blob/master/datastruct/elasticarray.h) and .c) allow me to write

        ELASTICARRAY_DECL(STRLIST, strlist, const char *);

and get a data structure STRLIST which contains an arbitrary number of strings and functions strlist_init, strlist_append, strlist_get, strlist_free, etc. for accessing the array. Compared to the non-macro approach of keeping track of the array size and resizing as needed, this makes code vastly simpler. (Of course, this sort of data structure is built into most non-C languages already.)

2\. My "magic getopt" ([https://github.com/Tarsnap/libcperciva/commit/53d00e5bd0478f...](https://github.com/Tarsnap/libcperciva/commit/53d00e5bd0478fcc89bc056d192a476fb89277a4)) allows me to something which looks and behaves just like a standard UNIX getopt loop, except with support for --long options. Yes, the implementation is mildly insane (and needs to work around a bug in clang!), but it allows for code which is vastly simpler than other getopt-with-long-options alternatives.

3\. My "cpu features support" framework ([https://github.com/Tarsnap/libcperciva/blob/master/cpusuppor...](https://github.com/Tarsnap/libcperciva/blob/master/cpusupport/cpusupport.h)) makes use of both macros and some tricky edge cases of C object linkage rules, but makes it trivial for me to add support for new CPU features.

4\. Soon to be released, the PARSENUM macro (WIP: [https://github.com/Tarsnap/libcperciva/blob/parsenum- additio...](https://github.com/Tarsnap/libcperciva/blob/parsenum- additions/util/parsenum.h)) which allows me to write

        PARSENUM(&n, "1234");
        PARSENUM(&x, "123.456");
        PARSENUM(&s, "123", 0, 1000);

where the first argument is a pointer to a variable of any integer or floating-point type to which is assigned the numeric value of the string in the second argument; for floating-point values and unsigned integers, the two- argument form range-checks the value against the bounds of the type, while the four-argument form range-checks against the provided bounds. (Basically, this is strtonum on steroids.)

In all of these cases, _you will never need to understand how these macros work_. Instead, you can simply treat them as language extensions which allow you to write cleaner and simpler code.

<comment><USER3> >1

I'm conflicted about this one. I choose not to try and emulate generics with macros because adding language features with macros is a terrible idea. On the other hand, I recognize the problem with void*. It's a matter for debate but I definitely fall on the "don't use macros for this" side.

>2

This is a case where I would rather write more code than rely on magic. You have to have this awful hacky opaque implementation in exchange for a trivial improvement in ergonimics. No thanks.

>3

I mean, just look at this code. Or better yet, have someone else look at it. This is totally unreadable and unmaintainable, all for a marginal ergnomics improvement.

>4

Just use strtol or strtof. Do you really run into this that often?

All of these are demonstrating exactly the problem I have with a lot of C authors. You build these esoteric systems that use heaps of unmaintainable, unreadable code to provide marginal gains elsewhere.

<comment><USER2> _Just use strtol or strtof_

Which of these is more likely to have bugs?

        int i;

        if (PARSENUM(&i, s, 0, 1000))
            err("Invalid input: %s", s);

or

        int i;
        long l; // need a temporary long to avoid overflow
        char * ep;

        errno = 0;
        l = strtol(s, &ep, 0);
        if ((ep == s) || (*ep = '\0'))  // make sure we parsed a number and don't have trailing garbage
            errno = EINVAL;
        if ((l < 0) || (l > 1000))
            errno = ERANGE;
        if (errno)
            err("Invalid input: %s", s);
        i = l;

_You build these esoteric systems that use heaps of unmaintainable, unreadable code_

Not at all. The point is to have self-contained routines which Just Work in order to ensure that the rest of the code is easier to read and maintain.

<comment><USER3> To be honest I would just have your library offer a function that does it your fancy way. I agree that there could be better integer parsing functions, I disagree that they should be macros.

>Not at all. The point is to have self-contained routines which Just Work in order to ensure that the rest of the code is easier to read and maintain.

Self-contained routines that are completely unmaintainable and unintelligible to anyone but you, though. Not worth it.

<comment><USER2> _To be honest I would just have your library offer a function that does it your fancy way._

It's not possible to have a single function do this. Not possible to have any finite number of functions do this if, like me, you want to support all floating-point and integer types.

 _Self-contained routines that are completely unmaintainable and unintelligible to anyone but you, though._

All of my macros are intelligible to anyone who understands the C preprocessor.

More to the point, why do they _need_ to be maintainable? When was the last time you maintained the strtof function in your C library?

<comment><USER4> > More to the point, why do they need to be maintainable? When was the last > time you maintained the strtof function in your C library?

A few years ago. [https://sourceware.org/bugzilla/show_bug.cgi?id=15744](https://sourceware.org/bugzilla/show_bug.cgi?id=15744)

Acting like you can get anything done right in C simply because it's self- contained is proven wrong every day. It's good practice, yes, but doesn't magically (we like this word now) make us immune to error. Everything needs to be maintainable, even if it is proven to be correct, for the simple reason that we can't just replace broken pieces of code with the same simplicity we can replace a broken fridge.

Also, if there's anything we know about code, is that we are constantly trying to invent new ways to expose it to a new interface - thereby breaking it.

<comment><USER5> > we can't just replace broken pieces of code with the same simplicity we can > replace a broken fridge.

Sure we can. Recompile glibc, dynamic linking, pow.

I wouldn't say that bug you referenced is a strike against C; it could happen in any language that was locale-aware and parsing floats.

For what it's worth, these macros in libcperciva are perfectly readable and maintainable:

      #define ELASTICARRAY_DECL(type, prefix, rectype)			\
      	static inline struct prefix##_struct *				\
      	prefix##_init(size_t nrec)					\
      	{								\
      		struct elasticarray * EA;				\
      									\
      		EA = elasticarray_init(nrec, sizeof(rectype));		\
      		return ((struct prefix##_struct *)EA);			\
      	}								\
      ...

The advice should really be "be careful, it's really easy to write shitty macros, so don't".

<comment><USER4> > Sure we can. Recompile glibc, dynamic linking, pow.

Oh, so I have to maintain glibc. That's the alternative, we are in complete agreement.

> I wouldn't say that bug you referenced is a strike against C; it could > happen in any language that was locale-aware and parsing floats.

I was responding to a very specific (and pointed) question.

> For what it's worth, these macros in libcperciva are perfectly readable and > maintainable:

I'm not contesting that, they might be. The one you list looks fine at a glance, but that doesn't prove anything.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> >Do not use macros. Do not use a typedef to hide a pointer or avoid writing "struct". Avoid writing complex abstractions. Keep your build system simple and transparent. Don't use stupid hacky crap just because it's a cool way of solving the problem.

Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros or custom abstractions.

<comment><USER7> > _Do not use macros._

Sir, yes, sir. I will throw away "offsetof" and "container_of" right now, just give me a moment.

> _Do not use a typedef to hide a pointer or avoid writing "struct"_

Somewhat agree with the former, but completely disagree with the latter. If there's a single thing that is not right with C is its excessive verbosity in places where none is needed.

Not typedef'ing your structs forces you to use extra 7 characters per type mention for no clear benefit. To put it differently - if NOT having "struct" in front of a type name has _any_ effect on readability/maintainability of your code, then there are deeper problems with your coding style that won't be solved by dragging "struct" around.

<comment><AUTHOR> >Not typedef'ing your structs forces you to use extra 7 characters per type mention for no clear benefit. To put it differently - if NOT having "struct" in front of a type name has any effect on readability/maintainability of your code, then there are deeper problems with your coding style that won't be solved by dragging "struct" around.

The benefit is to readability. You should treat structs differently from scalars, and the code should make the distinction apparent. You should not generally, for example, pass structs by value. This is just laziness.

<comment><USER7> Not sure I follow.

> scalars

So you would typedef the scalars then? If you don't, then scalars will be the built-in types (which you'd presumably know well) and then all other type names will be typedef'ed structs/unions, still making it trivial to recognize them as such.

<comment><USER3> Yes, I think typedefing scalars is fine. Typedefs are useful for abstracting the underlying storage mechanism for a scalar (so you can i.e. change it on different archictures or in a future release without breakage), not for saving yourself 6 characters of typing.

<comment><USER8> Typedefs are useful for creating short-hand names for otherwise long or complicated type definitions. Saving 7 (6 for 'struct' \+ space) characters is as good use for typedef as any other.

<comment><USER9> You only have to write each set of seven characters once; yes, typing will require a bit more effort. However, we shouldn't optimize code for the ease of writing, we should be optimizing for the ease of reading. Write once, read many.

`struct foo` is a bit more instructive when understanding code than `foo`; at worst, they read the same to someone familiar to the codebase, at best they prevent the need to flip back and forth to the type definitions.

<comment><USER10> >Typedefs are useful for abstracting the underlying storage mechanism for a scalar (so you can i.e. change it on different archictures or in a future release without breakage), not for saving yourself 6 characters of typing.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER11> 1) Learn Compiler Design

2) Write a Compiler for a better language

3) In new language, write a compiler for your new language

4) Retire from C programming, occasionally come to Hacker News to reminisce about C programming and ways to avoid shooting yourself in the foot

<comment><USER12> or

1) Learn Embedded Design

2) Stay in C for another few decades

<comment><USER13> I'm in embedded, but I have a fair measure of autonomy so I've got some Rust code on our device. If nothing else, the cross-compilation story for Rust is absolutely _beautiful_. Just stick the toolchain path in a config file somewhere.

</comment></comment></comment><comment><USER14> TL;DR: move on, nothing serious in this article. Just barking useless advice and spitting insulting nonsense.

<comment><USER15> Just like your worthless comment. The irony.

<comment><USER14> I posted it in hope to prevent someone, somewhere, to waste some of his time.

</comment></comment></comment><comment><USER16> >>Avoid magic. Do not use macros

What a put off!!!

If you are programming in C in the 21st century then you better know what you are doing. And this whole advice is for dilettantes (no offense).

C is no longer a choice language to demonstrate high level programming principles (not that you can't do it but it's not for the lazy), there's a host of other languages that do that better. But if you are interested to reach close to the machine (eg: you program needs a direct view of memory) then C is 'the' choice even today.

Look at the kernel list.h [0], it's a beautiful piece of code, and how concisely it uses macros. So the real advice to those starting out in C is to be bold and get immersed in all the things that people say you should not do and then let simplicity emerge.

In other words, 'simplicity' of the novice and of the experienced share the same word but are two different concepts from two different points of view.

[0][https://github.com/torvalds/linux/blob/master/include/linux/...](https://github.com/torvalds/linux/blob/master/include/linux/list.h)

<comment><USER17> I'm coding in C89 because I'm writing software for industrial embedded controllers. Future maintainers of this software are more likely to be electronic engineers than programmers, so "keep it simple and don't use magic" is actually extremely good advice.

That said, my code does use a couple of macros, but only to do stuff that would be very long-winded and/or impossible without, and using malloc at all is very much frowned upon: storage should either be declared ahead of time in special .var files, or on the stack.

<comment><USER18> Yeah, in general I agree with the article, the 'malloc all your memory' part is something I disagree with heavily. Outside of the fact that many malloc and calloc implementations don't particularly deal well with integer overflow[0], it introduces non-determinism into your code. MISRA C even forbids the use of dynamic memory allocation.

In fact, the environments where C shines oftentimes won't even have a dynamic allocator...

[0] Try allocating ((size_t)-1) bytes. Quite a few implementations will give you a pointer back! They'll add some space for a header, or round up the size to the nearest n-byte boundary. This problem's compounded by the fact people assume passing unsanitized input to malloc effectively sanitizes it.

</comment></comment></comment><comment><USER19> > GNU is a blight on this Earth, do not let it infect your code.

Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

<comment><USER20> It's "All the world's a VAX" in its new form, where you depend on some language/library feature that's actually not in the standard (IIRC alloca and preprocessor extensions are common culprits).

And then suddenly you're on a different platform and discover that you can't rely on that -- pretty bad if it's in a central part of your system (like trampolining functions for your toy lisp).

On the other hand, you might run into the same issues if the standard support is sub par. People used to declare K&R-style functions for ages after ANSI was passed, and I wouldn't bet a central part of my system on C99.

<comment><USER19> So in your opinion the problem is "only" one of portability to non-gnu systems?

I thought the author also implied that GNU was technologically inferior and/or problematic. That would interest me...

<comment><USER20> Probably the ubiquitous "bloat" issue some die-hard C-heads have. But that's his prerogative, I was just pointing out that the specific context points towards portability issues.

<comment><USER21> There is quite a lot of GNU code written in C.

However, since gnu is a political umbrella project which does not necessarily value code quality, we see a lot of unnecessary complexity arising from the focus on creating working "free" software and not minding the quality much.

Anyone who ever touched GNU autotools will confirm that the bloat issue is real. No need to be a diehard C head.

</comment></comment></comment></comment></comment><comment><USER22> I disagree with quite a few of them. The title should be "Principle for C programming ON UNUX BASED SYSTEMS". C programming is quite a bit wider that this, and some of the typical points here are no-no if you want to write /portable/ C.

For example, "Do not use fixed size buffers". It's all very fine, but 1) it can be exploited _as well_ if someone managed to fudge the size you are going to allocate, and 2) on some platform, you don't have/want malloc(). So it's a lot better to have a fixed buffer _and check the sizes carefully_ before copying into it.

Another one I dislike (but it's personal preference) is the 'use struct for pointers to structs' \-- well, nope, I don't like that, it's unnecessarily heavy. I typedef my structs all the time, and call them something_t, and * something_p. It's easier to rework, rename, search for and it's quicker to type so makes the source code lighter to read. I _know_ it's not popular, and for example the kernel guidelines agree with you, but I don't.

As for "no circumstances should you ever use gcc extensions or glibc extensions" well sorry, I also disagree here. I love the 'case X..Y:' syntax for example and it's been around for about a million years. It's not because the C standards prefer adding idiotic syntax instead of _useful ones_ like this that I'm going to stick along and limp when there is a perfectly nice, clear and very readable alternative.

Another one I _love_ but can't use are the sub-functions. Now _what also_ would have been a lovely extension if the runtime had been perfected a bit, but it was never 'finished'. Speak of easier code to read when your qsort() callback is listed /just above/ the call to qsort().

Another extension is of course the __builtins that you actually do need on modern systems. Like memory barriers, compare and swaps, ffs, popcount and so on. Of _course_ I can have an explicit function to do it (in the case of the last 2), but that's the sort of things that _ought_ to be in the C library anyway. So I'll use these, thanks.

As far as the rest of the article about the process, your code reviewers and so on, in many places and on many projects (open source ones are a case in point) you don't have the freedom/time to do that. The rule is ' do as best as you can' \-- and that _ought_ to do it in many cases.

<comment><USER23> > 'I typedef my structs all the time, and call them something_t, and * > something_p'

I wish people would stop perpetuating this particular naming convention. Its in violation of POSIX which specifically reserves the entire *_t 'namespace'. Obviously its fine if this is done on a system or environment for which this is irrelevant, but its best avoided otherwise.

<comment><USER24> The reality is that if you are creating a library you probably should prefix your types and functions anyway. And rely on the prefix to minimize collision probability. So it doesn't really matter if you put _t and the end of your type aliases. You will probably not get the collisions anyway. Unless POSIX is going to suddenly introduce mylib_array_t or something.

<comment><USER25> No, but your compiler MIGHT decide in a future release that it's a whole lot faster to ignore the header files for standards types and definitions and just copy a pre parsed version of the struct into the symbol table when the header is included. It might look at the _t and decide nope, I don't have a definition for this so it's an error, despite your own definitions.

This probably won't happen. But if it does you don't have any grounds for complaint really.

<comment><USER24> The compiler to do that would also need to drop C standard compatibility (section 7.1.3 of C99). Which is probably a good reason to complain and to just stop using that version of this purely theoretical compiler.

</comment></comment></comment></comment></comment><comment><USER26> Feels too heavy on "donts." I imagine the motivation the desire to be heard and understood. But I also need something simple, like "keep it simple, stupid" or "first have a working product that anyone could read". Positivity >> negativity.

<comment><USER27> I guess there are 'donts' because people need help with the keep it simple part, they are quite comfortable with the stupid part.

<comment><USER26> "nobody's grading your code by how many abstractions and topics from a textbook it employs."

<comment><USER28> That said, people sometimes ate grading your code based on performance. Good algorithms often win over simplistic ones.

<comment><USER29> I'd say when you have big n, smart algorithms O(n) are better. But most of the time you have small n. better to optimize just the real big N in your program, for what you profiled, than using complex and "optimized" algos when N<1000.

(I cannot retrieve the article this was taken from)

<comment><USER30> "It's okay for my n!" [http://accidentallyquadratic.tumblr.com/](http://accidentallyquadratic.tumblr.com/)

</comment></comment></comment></comment></comment></comment><comment><USER31> I've recently been reading Scott Meyers' Effective (Modern) C++ books. They are fantastic - can anyone recommend something similar for C? I.e. books that assume you're familiar with the language, but explains pitfalls and best practices in a practical way.

<comment><USER32> Deep C Secrets.

<comment><USER33> That book is great, very in-depth, yet fun to read.

One caveat, though, this book is from the mid-nineties, so some parts are a little dated. Still, very much worth reading.

</comment></comment></comment><comment><USER34> One thing that comes to mind is that young people today are weaned on oo languages and may find it hard to adopt the good old-fashioned non-oo style typical for C.

For example, intrusive data structures may seem like an anti-pattern to oo programmers, while they feel perfectly ok for a C programmer. On the contrary, C programmer may find non-intrusive data structures to be an anti-pattern as they require extra memory allocations.

</comment><comment><USER35> The problem with all this advice is that C lacks so many amenities of modern programming languages (no module system, no opaque types, no automatic memory management or RAII, no closures, no parametric polymorphism, no subtyping) that working around these limitations is bound to violate some of it.

The same strict rules that you can afford to adhere to in other languages do not work for C: with C, the often delicate balance of tradeoffs can tip either way.

> Do not use a typedef to hide a pointer or avoid writing "struct".

This really seems to fly in the face of the idea of information hiding, at least when listed as an absolute. The client of a module does not need to know whether (say) a handle is an int or a pointer.

> Do not use macros.

> Never put code into a header. Never use the inline keyword.

This just doesn't strike me as good advice. You're creating potentially costly abstractions. For example:

      for (foo_init(&foo); !foo_done(&foo); foo_next(&foo)) {
        ...
      }

Without macros or static inline functions, you're creating overhead. Overhead that other languages with proper module systems can avoid, but not C, so you have to work around it. Sometimes it's not an issue, sometimes this is code that you want to use in a hot loop. By not having low-overhead abstractions, you're encouraging manual inlining or hacking around their lack when writing performance-critical code (and if you aren't writing performance-critical code, why are you using C)?

Macros are also the only alternative that you have in C to compensate for the lack of closures. They aren't closures, and they aren't even good macros, but cover some of the same use cases.

> Do not use fixed size buffers - always calculate how much space you'll need > and allocate it.

This is not exactly wrong, but it only talks about half of the problem. The alternative to fixed size buffers are manual memory management or alloca(). Manual memory management is also error-prone and alloca() can blow up the stack. It's not that people necessarily think that fixed size buffers are good: they're choosing between various pain points. Fixed size buffers with a generous upper limit that is properly enforced can make for a perfectly viable trade-off.

> Keep your build system simple and transparent.

This is a bit vague. What's "simple and transparent"? At some point, you'll have to deal with things like how to figure out dependencies, for example. Preprocessors and code generators are common in C projects, often to reduce common C pain points.

</comment><comment><USER36> These points may be especially important for C programming, but most of them really apply to programming in any language.

</comment><comment> GuB-42 I mostly agree, however I don't like the idea of making code easy for novices to understand as a primary goal. That's because may imply not using some powerful constructs out of fear they may not be well understood by beginners. I think it is better to imagine that the next person reading your code will be better than you and that he is going to judge you. So don't hold back, use your clever tricks, but make sure you use them correctly otherwise you will look like a fool.

Also, never say never. All non-deprecated features of the language can be used : goto, inline, macros, you name it. You just need to know how to use them wisely.

</comment><comment><USER37> > Use only standard features. Do not assume the platform is Linux

I'll decide what platform I am targeting, thank you. I don't feel any obligation to support obscure OSes if I am just targeting linux. I might as well use useful linux-specific and GNU userland features, they are helpful.

<comment><USER4> "Do not assume" doesn't really mean or imply "do not target", so stop being defensive. It's good advice.

<comment><USER38> Targeting expresses expectations about an environment. "Do not assume" would be contradictory to those explicit expectations.

<comment><USER4> And since we can follow that thought process, we are smart enough to infer the meaning of the advice given ("do not assume") in the proper context, can we not?

It's obvious to me we both can, so why the hell are you wasting our time with useless pedantry?

<comment><USER38> Why are you inferring meaning when the article's author used two paragraphs and numerous examples to illustrate his point unambiguously?

The article is clearly heavy on the absolutes (eg: "Under no circumstances should you ever use"), and the grandparent comment critized this, and provided a good counterexample.

But you, ironically, chose to assume what the author meant by "do not assume".

<comment><USER4> OK, _now_ I know you're trolling.

</comment></comment></comment></comment></comment></comment><comment><USER39> All sounds good in theory but in practice in a large enough project many of the suggestions are not practical.

Recently I was looking at rsyslog's source code.

Look at this "simple" file for example, [https://github.com/rsyslog/rsyslog/blob/master/plugins/omstd...](https://github.com/rsyslog/rsyslog/blob/master/plugins/omstdout/omstdout.c)

It's an output module for rsyslog that logs to stdout.

I wanted to gouge my eyes out.

<comment><USER3> This code fails to follow many of my suggestions.

\- Liberal use of macros

\- Horribly unreadable coding style

\- Needless use of compiler extensions

\- Very poorly organized code

This is awful code because the authors are morons, not because the language is bad. They could stand to read this blog post.

<comment><USER40> I did find this line of code quite entertaining:

         if((r = write(1, toWrite, len)) != (int) len) { /* 1 is stdout! */

If you're going to go to the effort to add the comment, why not just use stdout instead of 1?

<comment><USER29> indeed, it's just a naive example but wouldn't something like

        int written = write(STDOUT_FILENO, toWrite, len);
        if (written != len)
            { ...

be simpler ?

</comment></comment></comment></comment><comment><USER41> __Do not use magic. __— Strongly agree.

 __Do not use macros. __— Absolutely I agree: I involuntarily grimace whenever I look at and /or things like Boost MPL, or the wartier corners of the Python C-API's underbelly, etc. I only use macros as straight-up batched ⌘-C-⌘-V:

        #define DECLARE_IT(type, value) extern const type{ value }
        DECLARE_IT(int, 0);
        DECLARE_IT(int, 1);
        DECLARE_IT(float, 0.0f); // etc
        #undef DECLARE_IT

__Do not use typedefs to hide pointers […] __— I cannot stand it when people do this. That asterisk is as syntactically valuable to you, the programmer, as it is essential to your program's function. If the standard library can slap asterisks on file and directory handles than so can you (and by "you" I specifically include whoever wrote the `gzip` API among other things).

 __[…] or to avoid writing "struct" __— Huh, actually I feel the opposite, I think all those "struct" identifiers are clutterific, much like excessive "typename" id's in C++ template declarations. But so aside from the points where I totally disagree with the author, I absolutely feel the same way 100%.

</comment><comment><USER42> interesting points. the maintainability part is freaking important but i guess you truly realize it only when you got bitten by it several times. some other details i don't necessarily agree with, like buffer sizes if you program for embedded devices or if you have real-time constraints.

</comment><comment><USER43> Made me think about the line in Full Metal Jacket: "C is my programming language. There are many like it but this one is mine." [https://www.youtube.com/watch?v=nkGIxGdZoYY](https://www.youtube.com/watch?v=nkGIxGdZoYY)

</comment><comment><USER44> Thanks for the read. Very educational.

I would suggest increasing the font-weight of your bolded text. I could not differentiate the two when skimming over the article; only when I read very carefully did I notice that you had somethings bolded.

</comment><comment><USER5> I'll wade in a little.

> Don't use macros.

> Don't use the inline keyword

> Never put code into a header

I disagree with these. It's often critical to avoid a function call in hot paths, and if you don't use macros or inline you have to resort to copy/paste, which is error-prone and hampers maintainability.

It's also the case that C is a rather inflexible language. Macros can be extraordinarily helpful in reducing boilerplate: in unit testing, for example. I won't argue that macro definitions are the easiest things to read (usually they're OK but they can get pretty arcane), but I do think something that cuts a file down from 8,000 lines to 1,000 is at least worth considering.

Macros can also help you maintain type safety. Colin Perciva demonstrated this a little with his elasticarray, but khash is another example of using macros to dynamically create type safe data structures. It can also help the compiler optimize your code.

> Don't use fixed-size buffers

Everything is a fixed-size buffer until you change its size. If you malloc a buffer of 1024 bytes and read 1025 bytes of user input into it, you overflowed anyway. The principle ought to be "check your bounds", which applies whether your buffer is stack/heap.

> Do not use a typedef to hide a pointer or avoid writing "struct".

I'm with you on pointer hiding (looking at you FreeType), but "struct" is just far too verbose. You don't accidentally pass things by value because the compiler will tell you you're passing the wrong type. You won't think it's actually a scalar because you have a grand total of 3 scalars in C (bool/int/float), and if you don't know the types you're working with in your functions you should probably look them up.

You probably don't think this is a big issue because you don't adhere to 80 columns in your code (I looked @ your GitHub briefly), but let me tell you you run out of space real quick, and "struct" is practically meaningless.

I found a good example:

      static void set_background(struct wl_client *client, struct wl_resource *resource,
      		struct wl_resource *_output, struct wl_resource *surface) {

vs.

      static void set_background(wl_client *client, wl_resource *resource,
                                                    wl_resource *_output,
                                                    wl_resource *surface) {

These are obviously not ints, it's a lot easier to read, and it fits in terminals. "struct" is honestly just noise.

> GNU is a blight on this Earth

Come on now. I hate GNU indentation as much as any reasonable person, but I don't think we need to go this far.

\---

Unrelated: aerc looks great! I've been thinking about moving off gmail and moving more of my life back into the terminal (I used to be all mutt and IRC and now I'm gmail and hangouts :/ ), and I really like aerc's well-organized code. Nice work.

<comment><USER3> >I disagree with these. It's often critical to avoid a function call in hot paths, and if you don't use macros or inline you have to resort to copy/paste, which is error-prone and hampers maintainability.

This advice is to be taken with a grain of salt, as with all programming advice. If you have a hot path, you should do whatever is necessary to meet the requirements, including macros or inline functions. The caviat, though, is that performance critical code that demands that is rare.

>It's also the case that C is a rather inflexible language. Macros can be extraordinarily helpful in reducing boilerplate: in unit testing, for example. I won't argue that macro definitions are the easiest things to read (usually they're OK but they can get pretty arcane), but I do think something that cuts a file down from 8,000 lines to 1,000 is at least worth considering.

I'm dissatisfied with all unit test frameworks for C that I've encountered. I briefly gave an example of how it might be done better in an unrelated blog post, would like to hear your thoughts: [https://drewdevault.com/2016/07/19/Using-Wl-wrap-for- mocking...](https://drewdevault.com/2016/07/19/Using-Wl-wrap-for-mocking- in-C.html)

>Macros can also help you maintain type safety. Colin Perciva demonstrated this a little with his elasticarray, but khash is another example of using macros to dynamically create type safe data structures. It can also help the compiler optimize your code.

I mentioned in response to cperciva's post that this is a tricky one. I acknowledge both sides of this discussion as valid but fall on the "just use void*" side. Not sure how it helps the optimizer out, though.

>Everything is a fixed-size buffer until you change its size. If you malloc a buffer of 1024 bytes and read 1025 bytes of user input into it, you overflowed anyway. The principle ought to be "check your bounds", which applies whether your buffer is stack/heap.

Well, I didn't say to just use fixed size buffers on the heap. I said to measure what you need and allocate that much. I probably should have phrased this more about just checking bounds in general, though.

>I'm with you on pointer hiding (looking at you FreeType), but "struct" is just far too verbose. You don't accidentally pass things by value because the compiler will tell you you're passing the wrong type. You won't think it's actually a scalar because you have a grand total of 3 scalars in C (bool/int/float), and if you don't know the types you're working with in your functions you should probably look them up.

Addressed in other comments.

>You probably don't think this is a big issue because you don't adhere to 80 columns in your code (I looked @ your GitHub briefly), but let me tell you you run out of space real quick, and "struct" is practically meaningless.

I actualy do, but I use 4 wide tabs, and as in all things I permit the occasional exception to the rule.

        static void set_background(struct wl_client client,
            struct wl_resource resource, struct wl_resource _output,
            struct wl_resource surface) {

I don't mind adding the extra newlines. It's not a big deal. These standards also evolve over time, and I've become more strict (check out chopsui for more a recent C example). I'm also lenient on columns from pull requests. I actually code on a VT220 sometimes, I do value width :)

No comment regarding GNU.

>Unrelated: aerc looks great! I've been thinking about moving off gmail and moving more of my life back into the terminal (I used to be all mutt and IRC and now I'm gmail and hangouts :/ ), and I really like aerc's well-organized code. Nice work.

Glad you like it! It's not ready for prime time, but maybe you'd be interested in contributing? I rely heavily on contributors to get so many projects done.

<comment><USER5> I'm not a mocking expert, but of all the solutions I've seen -Wl,--wrap=[blah] feels like the most straightforward, yeah. I also like how it's in your build system and you don't write a bunch of twisted code or auto-gen'd headers and redirects. It's appealing enough to make me wonder if there's an obvious reason people don't use it.

I'll put aerc on my list of projects to watch. I'm swamped with overly- ambitious hobby projects but sometimes I need a breath of fresh air :)

</comment></comment></comment><comment><USER45> this video: [https://www.youtube.com/watch?v=443UNeGrFoM](https://www.youtube.com/watch?v=443UNeGrFoM), from a talk by eskil-steenberg titled 'how i program in c' is, imho, pretty good as well.

</comment><comment><USER46> Great post, but most of it is relevant for all other languages as well.

</comment><comment><USER47> These principles, at least by name, apply in general, not just to C.

</comment><comment><USER48> Meh, skip on this one.

</comment><comment><USER49> 1\. The only reason to use C these days _is_ performance and portability. Write the code to your level of expertise or use a different language to cater to the 'du jour' audience.

2\. This was advice straight of Der lindens Deep C secrets back in the mid 90s. It wasn't always true then and it isn't always true now. I often use macros and don't find them a problem to understand in others code.

3\. Give me a break. Except when you don't need to allocate and manage memory which is almost every time you write a tool that does one thing well. This is not a good general principle.

4\. This is the way it works for me. Do it. Nope.

5\. Ok, some of this is common sense writing portable code. 'GNU is a blight on this earth': "..now we see the violence inherent in the system.."

6\. Yes, finally a good point but not about C per-se. 7\. Ok, but this is not about C per-se. 8\. Hrrmmm. A culture of blame is what produces restrictive rules like these.

This article is fodder for the Rust and other anti-c devotees here to glom onto and point out all the problems with the author and his language as the ultimate straw man. To me it sounds like this person wasn't writing C in the 90s.

</comment><comment><USER50> In case drewdevault.com has been blacklisted by your web proxy (as it is for mine), here's an alternate source:

[https://sircmpwn.github.io/2017/03/15/How-I-learned-to- stop-...](https://sircmpwn.github.io/2017/03/15/How-I-learned-to-stop- worrying-and-love-C.html)</comment>


Netflix's UX design is keeping people up at night - <AUTHOR> https://xd.adobe.com/ideas/perspectives/social-impact/sweet-streams-baby-netflixs-algorithms-genius-devious/ <comment><USER3> Does that really work on people? (Rhetorical questions, they wouldn't have been doing it this long otherwise) How?

I feel like Netflix is trying its hardest to stop me from watching.

Usually at the top is some show I have no interest in. That takes up most of the screen preventing me from seeing things I might be interested in.

Then I see My List: 1 show with new episodes. Great. It just happens to be the show they wasted over 50% of their website telling me about. Onward: A bunch of shows that I finished watching and that are either canceled, finished or have no new episodes. Why would I want this information?

Next line, "Continue Watching": 2 shows that I found so bad I stopped watching them (The Witcher and Criminal: Germany here)

Next line, "European Mind Game TV Shows". Sounds good. One show I might eventually watch. 3 shows I already watched… on Netflix. 2 shows that I think I checked and disliked but can't say for sure because Netflix keeps changing their covers. I'd rather spend the time ranting about their dumb UI than being annoyed by re-checking the synopsis for a show I decided against.

Trending Now: 5 shows I didn't like (where is that "Never annoy me with this cheap shit again"-button?), one that might be interesting.

So, Netflix used up 2 pages on a Full HD Monitor and with careful checking I realized one show I like has new episodes, and one new show could be interesting. But I don't usually expend this much effort into finding something to watch. So instead I usually find a new show elsewhere and only use the search or a meta stream search to find out if something is on Netflix and don't bother otherwise.

The only site I know with a worse UX than Netflix is Amazon Prime Video. Yet I keep reading that their design improves engagement, do people not care what they watch and instead just rewatch everything all the time? I really don't get it.

<comment><USER4> Someone once pointed out to me how "engagement" is often misread by companies. The product team makes a change to their website or app and suddenly engagement skyrockets. They think, "Wow! That change really got people to use our product. Let's do more!" when, in reality, the change they made is initially so confusing that their users spend more time than they would otherwise just trying to find their way around all the new changes. This, coupled with new product owners, product managers, and executives who feel like they need to justify their positions and the easiest way to do that is to "improve" the product and we have a negative feedback loop that is perceived by everyone within the company as a virtuous cycle. All the while they're just pissing their customers off.

<comment><USER5> The experienced managers know that the difference, but others could either be easily fooled or gaming the statistics to help boost their internal politics standing.

The bigger problem is when these engagement bumps are valid but destroy long term value in the cohort. The auto binge optimization makes viewers more cautious about opening the Netflix app altogether.

This happens with things like fast food restaurants. Subway expanded rapidly, and then tried holding up their sales with discounts. How long can someone eat at Subway weekly or daily before they never want to go there again? The bar is so high, you are way betting off starting a new franchise brand than trying things like removing yoga mat chemicals from your bread or hiring a new mascot who isn't a child rapist.

<comment><USER6> > How long can someone eat at Subway weekly or daily before they never want to > go there again?

Bread is one of only a very few foods that seem to be immune to "food exhaustion", the tendency to want to stop eating something you've been eating. (Milk is another, but I have a feeling that only applies to lactose-tolerant people.)

So if you varied the fillings, probably indefinitely. How long can you have cereal for breakfast before you never want to eat cereal again?

<comment><USER7> It's not just bread, though. It's subway.

I believe the veggie option is still yesterdays hummus crudely spread around a bun with bell peppers, black olives, an raw onions. The meats are cafeteria tier, in fact I think the meatball sub recipe is the exact slop served in my old dining hall.

They undermined their masterful subliminal marketing on the entire millennial generation by raising the $5 foot long sub to near chipotle bowl price points, and in my city at least cheap excellent street food is already on every corner.

I only ever settle for subway, it's not a destination.

<comment><USER6> I happen to agree about subway, but that's a personal taste that immediately implies it shouldn't be able to run a store in the first place. "This is terrible food" just isn't the same argument as "it's good, but you get tired of it after a month". High sales that taper off aren't compatible with the first.

</comment></comment></comment></comment></comment></comment><comment><USER8> The author, Madeleine Morley, of this very well-written article seems to be working against her own best interest as far as sleep goes.

Quoting:

> I've always required television to get to sleep, and I'm not a good sleeper.

> Why watch the same thing if there was all this newness to explore? My > nighttime viewing hours grew later and later.

> For those of us who used television as a sleep aid, we now seem to be facing > a new phenomenon.

> All these streamlined UX features mean that when I'm tucked in bed in the > dark, I barely need to think about what to watch when I'm trying to get > myself to sleep.

I understand the idea of television as a sleep aid. I used to use music in the same way. But I don't think the Netflix UI is as great a contributor to Morley's issues with sleep as much as her sleep hygiene which uses "television as a sleep aid", an oxymoron at best.

<comment><USER9> I used to do this as a kid. In my family everyone was watching a television at almost all times when we were home. Naturally it was there when we would go to bed.

I recognized this was a terrible pattern. I began shutting off the tv when I was going to bed. Eventually I moved the television out of my bedroom.

This is learned behavior and it can be unlearned. There's one simple solution to the problem posed in this article. Get the tv out of your room; it's not doing anything positive for you and I'm fairly certain you won't crave to have it back once it's gone.

<comment><USER10> I heard an anecdote that there's a Feng Shui ritual to exorcise the demon that harms sleep.

They perform the ritual and then take the TV out of the room.

</comment></comment></comment><comment><USER11> For me, the Netflix user interface is a horrible experience that blocks me from finding the series I want to see.

\- I want vertical browsing \- I want to be able to remove items from the list, mark them "not interested"

Maybe some people prefer this layout. Fine! Make it optional. Give us the "pro" user interface as an option in the menu. My bet is all Netflix programmers want one. I can't imagine that there is one Netflix programmer who thinks this interface is how they would make it. This interface screams "marketing". Fuck those guys.

<comment><USER12> They are deliberately not providing the tabular list, categorization, and other features that most people would find useful. Most likely reason is, it would quickly reveal to broader audience how much content they really have and also how quickly they disappear.

<comment><USER13> I think the most likely reason is that highly functional and customizable interfaces remove the ability of marketers to implement coercive experiences like the article discusses. I see this all over the internet and apps. What used to be standard customization options are becoming rare. How can a company A/B test something if users are running hundreds of different customized versions of an interface? Better to keep things as standardized as possible to ensure the desired experience and facilitate fine-tuning.

<comment><USER7> Ultimately lazy. Everything can be controlled. Give me a list view, I block trackers anyway and am already not helping improve the quality of the data set.

Maybe I'm just pining for a streaming service in the terminal program.

</comment></comment></comment></comment><comment><USER14> Netflix's UI is designed to:

1) obfuscate its surprisingly shallow library

2) encourage user interaction (more telemetry data)

3) promote Netflix original content

As a user, I don't want any of this. A small cottage industry of alternative Netflix UIs has popped up, because sometimes you just want some good old fashioned filters and sorts.

A few examples:

[https://flixable.com/](https://flixable.com/)

[https://www.justwatch.com/](https://www.justwatch.com/)

[https://instantwatcher.com/](https://instantwatcher.com/)

<comment><USER15> I never understand the complaint of a small library for Netflix... there are way more things to watch than I have time for. More things are coming out than I can watch.

Who are these people who watch so much stuff they run out of things to watch.

<comment><USER16> I think watching TV has shifted to "I wonder what's on, that looks interesting I'll watch that" to "There's a million things on, but I just want to watch X, and if X is not available then there may as well be 0 things on".

I used to go to Netflix for a few core shows (and still do) but they've slowly moved off. 30 Rock, Buffy, Sunny in Philly - all are gone, which means the number of shows I actually care to watch on Netflix was cut in about half.

They may have a million other titles, but it's extremely rare that I'm in a "browse and pick something" mood these days.

It's also why I hate the fragmentation. All 3 of those shows are from different networks - one day they will all be on their own respective subscription based websites. And I'm gonna just go back to pirating.

<comment><USER17> > 30 Rock, Buffy, Sunny in Philly

> It's also why I hate the fragmentation. All 3 of those shows are from > different networks - one day they will all be on their own respective > subscription based websites.

All 3 of those shows are on Hulu, so you only need to sign up for one additional subscription. So far. I expect that the fragmentation will only get worse from here.

I subscribe to Hulu (Always Sunny, Brooklyn 99, Bob's Burgers, Rick and Morty), Netflix (Black Mirror, Arrested Development, Bojack Horseman, Great British Baking Show), and Disney+ (The Mandalorian). I'm paying $31 a month for these subscriptions. I keep wondering if I'd be better off buying DVDs/Blu-rays and ripping them all to a plex server instead, but that seems like a lot of work, even if it would pay off in the long run.

<comment><USER16> 'So Far' is the key. They also used to all be on Netflix.

Money isn't an issue, it's mostly just annoying to have N services to juggle. Pirating's really easy - I use exactly one pirating website, and it's free. Way simpler.

</comment></comment></comment></comment></comment><comment><USER18> I'm going to probably seem stupid here. I don't understand why Netflix should be obsessed with how long people stream. I keep seeing this metric and I don't get it for something subscription based. I have Netflix, I have no intention of getting rid of it but I do not watch it that much. It's not ad supported, so if they have my subscription isn't that enough? Who cares how long I watch?

At the current subscription cost, keeping Netflix is a negligible expense for me and I'm not wealthy. So long as they put out 3-4 interesting things to watch a year (be it originals or something licensed) I can't imagine I'd cancel. I'm not looking to fill my days and nights, just something to kill a little time here and there or unwind for an hour or so a day. Am I an outlier? Do sub numbers drop if users can't sustainably spend 4+ hours a day on their platform?

<comment><USER19> IMO, Netflix is at the stage where it collects mass preference to produce better movies by themselves, which creates a virtuous cycle for their bottom- line -- addiction to the platform of the mass & quality production.

I would think they will start charging more if the growth stalls AND enough stickiness of the platform is proven. Currently, they are making profits and growing in terms of revenue, so as long as the founder keeps the control and the company is profitable, I think it might make sense to pursue more subscription at the cost of short-term profitability.

</comment></comment><comment><USER20> The biggest (and worst) achievement of the Netflix UX is keeping people scrolling through lists (since almost nobody likes the blaring auto-playing previews of what's selected) and adding things to their lists but not really spending time watching movies or shows. This way, Netflix prevents its customers from spending time on competitors' platforms while also saving tons of bandwidth and other resources. It's a devious and genius UX!

Anyone from Netflix claiming that they truly want their customers to watch more on Netflix is delusional or lying or both! For example, Netflix customers have complained about the auto-playing previews for a long time and there's no solution from Netflix.

<comment><USER21> I'd argue it's a balance. While I agree it's logical for them to want to optimize a balance between watching and scrolling. They don't want you to scroll forever, otherwise you'll get bored and not watch anything, I can only tolerate searching for nothing for so long.

Do that enough times and you have a subscription cancellation fast approaching.

<comment><USER20> I don't have the link handy, but I remember reading that many (or most) Netflix users spend a significant amount of time managing and going through their lists to decide what to watch. Anecdotal observations and a handful of personal conversations have revealed the same. I don't think as many people are canceling for this devious UX to be a money problem for Netflix.

</comment></comment></comment><comment><USER22> Is it just me who feels strange when noticing that its on a Adobe Domain?

I mean objectively speaking it's all fine as it's on some form of "blog" for "interesting thinks about design". Which is what the article is about (design which keeps you watching). Still for some reason I can't pin down seeing it on a adobe domain irks me...?

</comment><comment><USER23> Can someone explain the reason behind the UX design? I have already paid for subscription and this is a yearly one too on auto re-enroll, why does Netflix have to do so much to make me watch? They only need to worry about providing great content. People already paid for it and they have algorithms that will guess what a user might like and bubble up those shows.

Why does it have to do one click play and auto play without even clicking? It's the most annoying feature ever and they seem to love it. There is no way to disable it. What are they getting out of it? It has gotten to a poi t where I expressly avoid Netflix unless I know there is a show I want to watch. All because of auto play. May be my hatred of it is extreme but I don't get the point of it.

<comment><USER24> Like with any subscription, if you don't use it much, you'll eventually realize it's not worth the cost and cancel it.

If people subscribe to 3 TV streaming services and realize they're mostly watching only 2 of them, they'll cancel the 3rd.

So for Netflix, it's extremely important that you watch a lot, because that's precisely what prevents you from cancelling.

<comment><USER25> So every minute spent watching Netflix is one minute not spent on Disney et al? Makes perfect sense to me in a space with increasing competition.

</comment></comment></comment><comment><USER26> I wonder if Netflix will eventually get rid of discrete episodes all together. Generally, the end of an episode is when people make a decision to stop or continue watching. If the goal is to maximize engagement, it seems like it would be beneficial for Netflix to get rid of those decisions-making points all together and make a season of television like a 9-12 hour movie.

<comment><USER27> I think most people would avoid the decision to _start_ watching something with a listed runtime of 9-12 hours. Netflix has already made sure that episodes transition automatically and seamlessly into each other, including reaching into the content itself to skip past long credits.

<comment><USER26> I would imagine going into it, people would optimistically assume they are only going to watch for 30-60 minutes, but end up getting hooked and watching for hours.

</comment></comment></comment><comment><USER28> I can't think of another service other than Netflix with such a hostile UX/UI. And this is in the age of popups galore. Everything about their UI is designed to keep me out of it as much as possible. My bingeing habits have drastically reduced and switched to alternatives like prime and Hulu.

1\. Auto previews is probably the worst thing they've come up with. I just want to read the description, not be assaulted with trailers and ad for the show. This means you need to scroll faster than it can be invoked. This also means a tense experience where I can't just take my time to find what I want to watch or I have to look elsewhere.

2\. Constantly moving 'Continue Watching' . I just want to get back to the show I was watching. Why is that so difficult to understand?

3\. Showing me previews by cutting out the end credits. It's like no one at Netflix has any idea how to watch a movie/show. Sometimes you want to reflect on what you just experienced. Or talk to the people around you about what happened. This is just extremely bad behavior on an app that's paid for.

4\. The discovery is straight up garbage. A rand() function on the top global watched tv shows/genre will result in a better selection then the crap their ML algorithm puts out.

Ironically all their 'engagement' tactics had moved my household from Netflix to Hulu and prime more. 2020 is probably when we'll cut the cord on Netflix.

Netflix had a huge advantage of being the first and the biggest in streaming services. They could have been easily the Google Search equivalent in their field. Instead, today their just one of the very many services with no discernible difference.

Netflix has solid engineers who were amazing to work with, but their product management teams would be people I'd never hire because it's very clear no one really understands the product.

</comment><comment><USER29> Maybe if Netflix had movies and TV shows that I actually want to watch, then I would stay up to watch them. Its become a recurring joke that every time I think "Hey this movie looks good, I'll check if its on Netflix", the movie has never once been available for streaming. This actually happened this weekend. I searched for 4 different movies, and in the "titles similar to {#4}" was one I was interested in so I watched it. I keep forgetting to cancel because I use Netflix so little now.

</comment><comment><USER30> The entire premise of this article appears to be based on the idea that peak viewing is from midnight to 2am.

That is most definitely incorrect.

Peak viewing, at least when I worked there, was during prime time in that time zone.

Except for kids shows. Peak viewing of kids shows was Saturday morning.

<comment><USER31> What was working there like? Does the whole "this is a professional sports team you might be cut at any moment" culture impart fear or undercutting or blame shifting?

I worked at Amazon and I found that the horror stories were _generally_ not true, but that if you ended up with the wrong manager could be very true. Always been curious about Netflix.

<comment><USER30> I loved working there. Everyone was great.

Everyone fears getting fired for the first few days, until you realize they don't really just fire you on a whim. Then you get over it.

People don't get fired for making mistakes, so there really isn't any blame shifting or undercutting. Making mistakes is encouraged -- it means that you're innovating and trying new things.

Making _the same mistakes repeatedly_ is what gets you in trouble.

The main difference between Netflix and other places is that at other places, when your current skills are no longer needed, they will move you into a new job and give you time to ramp up.

At Netflix, they will say, "here is a big fat severance check, let us know if you need any glowing references".

</comment></comment></comment><comment><USER32> This doen't seem to be particularly new or specific to Netflix. When I am reading a catchy book at night, I often read more chapters than I intended to, occasionally until deep in the night.

<comment><USER33> Same, plus I remember countless times I stayed up later than I should have as a kid watching network television as a kid in the 1990s. I guess Fox was fighting my sleep too?

The main argument seems to be that binge watching makes it worse. But in reality there's only a small amount of shows that are worthy of binge watching and Netflix has a very finite amount of them...per year.

</comment></comment><comment><USER34> I feel so seen! For a very long time, I couldn't sleep without watching TV shows on my laptop, to the extent that I'd have insomnia if the Internet went out. In fact, even though I've weaned myself off it for the past several months, I'd probably still have trouble sleeping if I didn't at least know I could watch reruns of 30 Rock if I had trouble sleeping.

More to the point: just like the author, there's a very particular kind of TV I'd watch to sleep: nothing for the first time, and nothing tense. The West Wing and the US version of The Office were both great for me, since there's so much of it to get through. I've probably seen every episode of The West Wing at least 15 times by now.

Which, to me, sort of answers/challenges the concern the author has about binge watching. On a normal night, I'd barely make it through half an episode before I'd notice time slipping as I watched, my cue that I'm nodding off and should shut the laptop. I'm never watching first-run stuff like Mindhunter or Russian Doll, the stuff Netflix really wants me to be streaming, because it'd keep me alert.

</comment><comment><USER35> What I find surprising is that despite their shallow catalog of content (my opinion), they fail to promote their shows to me that I'm actually interested in. When Stranger Things Season 3 was released and when The Witcher was recently released, it was no where on my home menus. Despite these shows being the exact genre I typically watch, I had to search for these shows. ?????!

<comment><USER36> Their machine learning algorithm is probably optimized to reduce churn and keep subscribers at any cost.

By making people search and find content, there might be some subconscious effect on people that makes them think the service has more value. Tricking people subconsciously means less cancelled subscriptions.

What's scary is that all these dark patterns Netflix and other tech companies are using are completely obfuscated. No one really understands what's going on because the patterns are part of some complex neural network. In the past they would have been shamed publicly for stuff like this, but now it's only 20% of their users who have such-and-such psychological profile can be exploited this way, while others can be exploited another way and no one knows what's happening.

My theory is the more powerful AI becomes, the more it will exploit human psychology until everything sucks. Everyone will have the overwhelming urge to keep spending money while being miserable because that's the optimal customer according to the AI.

<comment><USER37> > My theory is the more powerful AI becomes, the more it will exploit human > psychology until everything sucks.

It can hardly do worse than what human beings have done to themselves over the millennia and continue to do to each other every day. But it can probably do it faster and more efficiently.

</comment></comment></comment><comment><USER38> About a year or so ago I realized that I cannot pay attention to English dialog shows (I speak English as my native tongue). I would either look at my phone, or even worse, start doing work on my laptop.

I made the switch to International Shows (that are not in English) where I am forced to read subtitles. I am forced to pay attention. If I don't, I have to rewind or pause.

It's actually a great system b/c: #1 - Netflix has a pretty solid international library b/c they've been making the global push #2 - <USER2> country has some good shows (at least a few) #3 - It's pretty interesting seeing how the other half lives

Also, to a lesser extent, Hulu and Amazon Prime also have good international shows, often licensed from real studios operating in foreign countries.

Occasionally I will watch an English speaking show, but it's an exception now.

</comment><comment><USER39> It's still the best among the major streaming companies.

Amazon's is designed to sell you episodes, meaning that it's complete garbage for actually trying to view shows. Instead of coalescing all the seasons and episodes for a particular title, they'll break them up into individual seasons that are usually NOT in alphabetical or chronological order.

Hulu? I tend to watch a couple shows on Hulu when I'm not viewing live TV. It is ALWAYS a giant pain in the ass to find those two shows. If I were at a computer it'd be one thing, but I'm sitting there with a remote trying to input text into a search bar.

</comment><comment><USER31> I always wonder if the public considers the Netflix UX to be as bad as it is considered here on Hacker News. I've noticed this with Airpods too. We as (mostly) tech people will deride a product and predict it's decline but it will have record sales and seem popular in the world. I have heard a few grumblings about the content library out in the wild, but in general people seem pretty excited and keen on Netflix.

I know that everytime I happen to watch cable TV with commercials the experiences feels a bit dated; I can only imagine what it feels like for the 20 and under crowd.

</comment><comment><USER40> I love my Netflix subscription but absolutely hate their app. And to think that their software developers are among the highest paid in the industry! I fondly remember the old days, when they give is a long list of shows in a list from top to bottom. And you had an arrow to move your titles up and down. No fancy images and auto-play and atrocious design

</comment><comment><USER41> > I've always required television to get to sleep, and I'm not a good sleeper.

These two statements are correlated. Television in your bedroom makes you a worse sleeper, and you can immediately improve your sleep quality by removing it and keeping your room as dark as possible. I was skeptical of this, but after a month of insomnia, I went to a sleep lab for a consult and took all of their advice. I'm still not an amazing sleeper but it's been a huge improvement.

</comment><comment><USER42> > Good UX coupled with great television has a way of encouraging bad viewing > habits.

This reminds me of a project to make cigarette packaging _less_ convenient in order to discourage smoking.

[http://www.erikaskin.com/index.php?/projects/design-to- annoy...](http://www.erikaskin.com/index.php?/projects/design-to-annoy/)

</comment><comment><USER43> Why is Netflix such a big deal? It's on the front page constantly. Their catalog is not massive and there are lots of other roughly equivalent services too.

I think it's something that William Gibson notes that in the US in everyday language, phenomena are somehow always tied to brands.

<comment><USER14> There are definitely strong network effects at play - people want to be able to watch and talk about the same shows as their friends and family.

</comment></comment><comment><USER44> How does Netflix make more money the more users watch, if users pay a flat monthly rate, and they don't show ads? They have to pay more bandwidth costs, the more people watch. Seems they should optimize for users who subscribe then never watch.

<comment><USER45> That is a "keep users paying feature". If you watch netflix a lot, there is a slimmer chance of cancellation.

</comment></comment><comment><USER46> Can't people be grown ups and stop blaming UXs for their behaviors?

<comment><USER47> No. It's no different than advertising. You may think you are "mature" enough but it does impact how you behave in suttle ways

</comment></comment><comment><USER48> I know Netflix will never make the faceted search interface I've always wanted: Show me shows that are between 45-90 minutes in a particular genre, made in the 70s. Show me animated shows from Japan that are <25 minutes long. Etc.

</comment><comment><USER49> Netflix's UI is terrible for discovery, unlike the DVD days where I loved browsing it even if I wasn't going to watch.

I do doubt that it's UI really makes anyone watch anything or binge.

</comment><comment><USER50> Leveraging AI and ML making companies to increase their revenue multi-folds.

</comment><comment><USER51> Netflix's UI is probably one of the worst I've ever used.

Horizontal browsing on desktop (or even mobile for that matter), are you kidding!?

Mouseover will completely change the layout, etc. etc.

Just very bad in general.

</comment><comment><USER52> It always confuses me how authoritarians and their ilk always end up admitting they do the thing they are complaining about. It's like they are complaining to me for their lack of self control. In any case, Netflix does turn off if it thinks you are asleep. Or, you can configure your tv or Wi-Fi to turn off at a certain time, which is why my kids don't watch tv at 3am.

</comment><comment><USER53> _" The UX of the top streaming services are expertly designed to encourage me to binge and remain on the platform for as long as possible."_ \-- I don't quite understand this. If it would be an advertisement-driven platform, like Facebook, then keeping people on a platform for as long as possible would certainly make sense. From a business perspective, that is. However, for subscription-based ad-free platforms like Netflix, I don't really see how it benefits them (assuming that people stay within the same plan/tier).</comment>