Ask HN: How to build a resilient, scalable REST api that is open to the web? - <AUTHOR>

I'm thinking about the recent url-based api created by someone on here called mebe.co
How would you go about building somthing like this? Where would you host them?
I was thinking appfog for node.js to handle incoming http request and rabbitmq to queue asynchronous requests, reddis to support data. <comment><USER2> You should probably consider the process design more than the technology (for now).

Goals:

1\. Whenever receiving a request for processing, you should return a task identifier that can be used to check for progress (ex. you could simply store this in redis as 'TaskId', 'Url', 'FileId', 'Type', 'Status', 'OutputId' - with Type being the type of input: URL or FileId)

2\. Once the client received the TaskId, it can do a request to get the status, which would could be 'Pending' or 'Complete' with an URL to the output.

Process:

</comment><comment></comment><comment></comment><comment>=

Request Processing:

\</comment><comment></comment><comment></comment><comment>-

1\. Receive the request with parameters (can users upload files or simply pass through an URL?)

2\. Create a token based on the hash of the input file and the parameters supplied (ex. MD5 hash of the video, from time, end time of the video to capture).

3\. Check if a task identifier has already been assigned to the token, if it has, return it. This means the client will then do a request to check for the status and would receive { 'Status': 'Complete', 'URL': '...' } and can immediately access the output via the URL.

4\. If the video is uploaded, check whether it has been saved via hashing the file (ex. MD5), if it has then use the existing FileId, otherwise, save the file and generate a new FileId.

5\. Generate a new task identifier and create a task entry to store in redis that contains metadata about the task.

6\. Create a command containing the task identifier and publish it to the message queue for processing (which is asynchronous).

7\. Return the task identifier to the client.

Task Processing:

\</comment><comment></comment><comment></comment><comment>-

To process the video, you would simply grab the metadata from redis and update the progress as you go along. If the task identifier doesn't exist (no metadata entry on redis), simply abort the task processing.

Although this is pretty simple, you should focus on optimizing file storage (ea. don't store the same file twice and reference them by MD5 hash or the like and perhaps have a cleanup routine to remove rarely/once-off used files) and processing time (if the task has already been processed, simply return the output). You should also decide on limitations to prevent abuse (DOS/DDOS attacks, large file uploads, what the service can be used for etc.) and limit your liability.

Is this the answer you were looking for or are you asking about the specifics of implementation (technology wise)?

<comment><AUTHOR> It's 2 AM here, but I'm mustering up the strength to write this because the answer provided here is so detailed, so specific to my question. Thank you so much for taking the time to write all that. I am still reading it over and over to fully comprehend it all, there's a lot to take in.

I see now the thinking flow I have to change, I have been window shopping so to speak with frameworks, stacks.

iron.io is what I think will be used for converting long asynchronous task.

I wouldn't mindd specific technology stacks. it's either node.js or python. I built something in Flask (god bless it's heart) but I don't know if there are others who have made it scalable...

I keep hearing this idea from something like this <http://www.slideshare.net/norbu09/rabbitmq-couchdb-awesome>

Thanks again, but I need to hit the sack.

</comment></comment><comment><AUTHOR> As soon as as a user types that into the browser, a few things will happen of course at that exact moment an http request is received by ________.

and then it will call iron.io ironmq or something like that, put in a request to the queue, fire off some ffmpeg scripts in the ironworker asynchronously, receive message that it's successful, send back to the browser animated gif that has been rendered.

During this time, the user will just have to wait, until the task completes. I'm not sure if I would want them to time out because what if (edge case), someone decides to convert one of those "Nyan cat loop for 10 hours" videos, the server is stuck in a long task.

Then comes the question of whether the same long process will continue if some other user wants to test out this exploit. That's where I think persistent storage of the processed file would come in handy. the request url should first be scanned if it's existing in one of our previous url requests.

Redis could be used replacing rabbitmq or ironmq. but I'm think for spike cases, not in a sense that the app will become hugely popular overnight (although making it on the first page of news ycombinator would awesome), but certain users either being passionate users making lot of requests and malicious individuals abusing it.

I really don't want to block the api behind the http auth dialog or a web based login.

I envision it to just work like you would use google, except you can convert youtube videos to animated gifs, just by entering in the url.

Of course in the backend, I'd need extensive monitoring and realtime analytics would be cool.</comment>


Why I'm Using C - <AUTHOR> https://medium.com/bytegames/why-im-using-c-2f3c64ffd234 <comment><USER2> "Reliability" \- in a language with manual resource management and unsafe parallelism model? Really? BTW never heard of modern games written in C. Mainstream game engines (UE, Godot, Unity...) are written in C++ and C# and cover all major platforms and consoles. "Performance" \- Rust is probably more performant when it comes to code, and definitely more performant when it comes to development time. "Simplicity" \- primitivism is a closer definition.

<comment><USER3> Rust is not close to hardware as C is, so if need to do anything with hardware Rust still relies on majority of the code written in C. Performance wise today C is still faster than Rust in general.

Rust is still a decade or more away from anything serious like C. Majority of the functional Rust libraries today depend on underlying C libraries.

Rust may try to replace C++ but replacing C is far away dream.

Let's wait when Mozilla (origin and major supporter for Rust language) can release Firefox in Rust, until than it's still a popular experiment in systems programming area.

Rust does not run any critical component like Linux Kernel today, when it will be able to do it than it can be considered as real systems programming language challenger to C. Right now most of it's safety guarantees are not really battle tested like C.

<comment><USER2> "Rust does not run any critical component like Linux Kernel..." \- and the only reason why it is not happening (provided that C and Rust have perfect interoperability, more and more C/C++ developers get familiar with Rust) is the fact that Linus Torvalds convinced by voices from Ethernet socket not to use anything but C. I can't wait for him to retire so that Linux kernel devs could pick up more modern toolset

<comment><USER4> As much as I love Rust: As long as Rust doesn't support all platforms which the Linux kernel supports, it really is a no-go for kernel code in general.

<comment><USER5> "in general" is a bit strong; the maintainers have said:

> I spoke with Greg Kroah-Hartman, and he said he'd be willing to accept a > framework in the kernel for writing drivers in Rust, as long as 1) for now > it wasn't enabled by default (even if you did "make allyesconfig") so that > people don't _need_ Rust to build the kernel, and 2) it shows real benefits > beyond writing C, such as safe wrappers for kernel APIs.

[https://lwn.net/Articles/797828/](https://lwn.net/Articles/797828/)

<comment><USER4> That's why I wrote "in general": It's not yet suitable for most kernel code, just for some specific cases (i.e., optional drivers).

Hmm, maybe I should have written "...for _general_ kernel code" or "...for _most_ kernel code", that would have been clearer.

<comment><USER5> Ah yeah, I see that now... words are hard, I think you can read this both ways. Sorry about that!

</comment></comment></comment></comment></comment></comment></comment><comment><USER6> I use C(as a backend) because I understand it.

In reality I use anything that gets the job done faster. That usually means prototyping in C++,lisp, python, swift, java, perl, lua.

After I have the prototype I code it automatically with C, or minimal C++ and my own DSLs, done in Lisp controlling C, C++ code generation.

I have reinvented the wheel a lot. Someone told me you are not going to be smarter than a compiler, but having read several of them, they are so dumb, and they have to be because they are generic.

E.G In a project I was using std::vector and predicted the expected performance of the whole program by O notation and "on the park" calculation needs as X.

When I completed the program, it was X/1000\. Fair enough I made some stupid mistake...in the end I got X/100 performance and could not optimize farther.

I got so frustrated so I started replacing components to see if numbers improved. Replacing std::vector by a c vector made the program X/1.4!!

So I started studying std::vector implementation and it was a template of a template of a template... I could not wrap my head around such a mess.

My implementation was done in lisp with proper macros and was way simpler and efficient and generated c code, that was so easy (although tedious) to understand.

<comment><USER7> Could you perhaps elaborate on the LISP/DSL approach to programming that leads to efficent and safe C code?

Thanks.

<comment><USER8> I second this request!

<comment><USER7> A quick Google search gave quite a bit of results e.g. C-Mera [1].

[1] [https://github.com/kiselgra/c-mera](https://github.com/kiselgra/c-mera)

</comment></comment></comment></comment><comment><USER9> Ok,

I think since none of his reasons include I am doing system programming

I will debunk

Reliability: C is not the only language with a reliable ecosystem, and what should matter most is the reliability of the program, not the tools made to create the program, so in this regard, I think Rust, OCaml, C#, Java are all as reliable, and I would argue it is easier to write more predictable or reliable programs in them

Performance: Yes sure C wins almost every performance benchmark, but Rust is very Fast and Ocaml is also very fast so unless you are working on system programming stuff, I think you have better options that are more reliable and predictable

Simplicity: Here I would like to contrast simplicity of the tool vs simplicity of the product, complexity does not go away, complexity is abstracted, simple tool = complex product or process, complex tools on the other hand may allow you to create simpler tools and processes, if you use simple tools you will transfer complexity to your products, which I don't think is necessarily a good thing

<comment><USER10> Rust will frequently build code that will run in a comparable number of cycles, but can often run even faster as soon as you introduce concurrency. Safety isn't just some crutch to lean on instead of simply being really, really careful in C. Concurrent apps need a lot of guarantees for memory safety, and it takes a lot of mental energy to figure out how safe you really are. C devs often go overboard and do more than is necessary as a result.

</comment></comment><comment><USER11> While it is true that C perfectly matches the hardware, it imperfectly matches the rich software abstractions which are needed for moderate and large sized software. The lack of namespaces and sane object creation, destruction semantics etc, makes programming tedious.

A large proportion of code in many large C programs go into recreating imperfectly the features that are by default provided by richer programming systems. And that repeats for every large program you do. It quickly becomes boring and unenlightening, to recreate an exception handling mechanism or data structure implementation for the nth time.

Why would anyone not prefer not having to focus on the mere infrastructure, and rather direct directions on the interesting problems to be solved.

Another thing is that large C code bases tend to become ensconced in layers of preprocessor macros, which I think is a hack-y way of doing things.

</comment><comment><USER10> You'll build to almost the same number of raw CPU cycles executed for the code, but probably build a better-performing game in a language with safer/simpler concurrency/parallelism. Ever since futures (concurrency) has stabilised, rust's my first choice on this. Pretty much all of his points not related to the sheer age of C apply; you can even get the 0-byte-overhead webassembly if you go no-std, though I seldom forego something so useful that's smaller than the loading-screen background.

</comment><comment><USER12> It seems like many of the responses to this article are from Rust and other language fans (but mostly Rust). I think many people are reading what they want instead of what the author was trying to convey:

"This is the most important and only real non-negotiable requirement for me; the reliability and portability of the toolchain and the access it provides to system and device interfaces."

Rust isn't exactly reliable. Try to build Rust itself. There are all sorts of issues with resource consumption and parallelism, and it takes more CPU and memory than compiling an entire OS.

Rust's portability is strongly discouraged by the resources it requires. Many platforms REQUIRE cross-compilation because they don't have enough memory, and this makes it hard to say it's easily portable.

If you're a fan, you're easily going to overlook this. You probably don't care that more than half the world doesn't have computers which have the resources to run Rust. That's fine. You also say that people shouldn't be concerned with compiling their own stuff. That's fine, too. But there are people who like to create projects and write software that's as accessible as possible to most people, not just to some people and available to many others just as downloadable binaries.

If you're not the kind of person who wants a free and open software ecosystem where everyone can participate, not just those with the resources to buy fancy, powerful, multigigabyte, multigigahertz, multicore 64 bit CPUs, then Rust is fine for you. If you you care about accessibility to as many people as possible, perhaps you'd come to the same conclusions as the author.

<comment> loup-vaillant It seems you are working on a different set of constraints than the author's. The author was talking about making games. Those are generally proprietary, and even the free one almost always have binary distributions. Rust _itself_ likely have a binary package for your development platform of choice.

Likewise, cross compilation is likely not a problem. You don't develop _on_ the PS4 or Switch, you develop _for_ them. Sure, in practice, cross compilation in C and C++ is indeed a problem. I'm wondering to this day how that's even a topic. A compiler is just a goddamn translator, the target platform should naturally be independent from the source platform. Worst case, you need to recompile the standard library for the new platform. (I suspect this is related to the bewildering difficulty of linking libc statically.)

You do have a point, but it's much broader and much stronger than choosing C over Rust. We spend heaps and heaps of code solving problems that could be avoided in the first place. Niklaus Wirth's Oberon operating system required less than 10,000 lines of code, and now we need like 200 million lines?! No way we now have 20,000 times the functionality, so we can guess that current computing systems are at least 100 times too big (that is, comprised of over 99% accidental complexity, Brooks be damned).

I sometimes feel the only way to make software truly Free and Accessible (meaning, people have the right _and_ the means _and_ the ability to use & modify their software), is to remake everything from scratch, with the benefit of hindsight.

</comment></comment><comment><USER13> > Why on earth would someone would pick C to start a new project in 2020?

Please ask yourself this before writing any code (For a cross-platform game).

By just reading this, I thought to myself if I were to write a cross-platform game in 2020, Is C necessary to accomplish this? Perhaps anything C can do, surely Rust can do it safer and arguably better.

<comment><USER14> The biggest advantage C has over Rust is the sheer breadth of platforms. As a developer, I would always prefer Rust over C, if possible, but sometimes C is more realistic.

In most cases, C would only be more practical on obscure or outdated hardware, though.

<comment><USER15> I fear that we are slowly moving towards a situation where our underlying technology stack is written in languages that a diminishing number of people have seniority in.

96% of the Linux kernel is written in C ([https://github.com/torvalds/linux](https://github.com/torvalds/linux)).

<comment><USER16> The GitHub counters are not always accurate. 97.3% (if going by C (imp+header) and Assembly) of the kernel is written in C, with the rest being written in Assembly. Everything else is config files, scripts, tests, or docs. GitHub reports C++ and Objective-C; those are just .h header files.

Update: Got to my system so I could actually look at available files accurately:

      C Implementation (.c): 28269
      C Header (.h): 20250
      Asm (.S): 1323

Edits: Update section and removing "100% in C" and "5 sources files of assembly"

<comment><USER17> Eh, find -iname '*.s' in kernel source tree finds more than a thousand files and half a million lines in them.

<comment><USER16> I wasn't at my system when I wrote that and just checked (5 is way off the mark there). Should have followed my own advice and not used GitHub's counters :P

The counter reports 1.2%, but if you click on that to show Assembly files it only reported 5 code results (it's not actually showing all Assembly, so you then have to click on "Unix Assembly" on the side).

</comment></comment></comment></comment></comment></comment><comment><USER18> "Why I'm using medium to write this article."

I was curious about this, but medium wants me to create an account to read it. Oh well.

<comment><USER19> Block javascript on medium. Makes it much better, no nagging, no limitations... sometimes you miss an image or two, but the text is there.

<comment><USER20> For me this does not work anymore. What I do is redirecting the domain to the Wayback Machine.

</comment></comment></comment><comment><USER21> "But It's not just about running fast, battery life matters as-well. Fewer cycles means less battery consumption which is a major win if you ask me. As long as I can help it, I'll do my best to avoid draining a user's battery in five minutes."

I was thinking about languages in terms of ecology. I'm a Python fan and while its lack of performance never bit me in the real world, how many Joules would be saved if my apps were written in another language ? I'd love to see a study/comparison based on real apps (not algos implementations).

<comment><USER22> Here you go: [https://greenlab.di.uminho.pt/wp- content/uploads/2017/09/pap...](https://greenlab.di.uminho.pt/wp- content/uploads/2017/09/paperSLE.pdf)

<comment><USER21> Yes, thank you, I knew this study. I wonder how real-world apps would change (or not) the conclusions.

</comment></comment></comment><comment><USER23> The great benefit to C is that it doesn't change. You won't feel tempted to rewrite your entire project 3 years later with the newest features

</comment><comment><USER24> I wish the myth that C is simple would die. It has all sorts of complex nooks and crannies. Even some basic things like specifying types are quite insane (e.g. for function pointers).

<comment> loup-vaillant C gives you an initial illusion of simplicity, and being close to the hardware.

Then you learn about Undefined Behaviour.

<comment><USER17> The language would be _more_ complex if it tried to specify all behavior. UB allows it to be simpler.

Do not confuse simple with easy.

<comment> loup-vaillant I disagree. Much UB makes the language less orthogonal, and ultimately makes the specification _longer_. And more complex.

Classic example of illusion of simplicity: signed integer overflow. Going outside the range? Undefined. Left shifting a negative integer? undefined. You can't just assume 2's complement, you have to be aware of the Nasal Demons compilers are becoming increasingly apt at summoning.

Another one: out of bounds array index is undefined, _even if there was something of the right type there_ :

      #include <stdio.h>
      #include <stdint.h>

      typedef struct {
          uint64_t a[8];
      } blk;

      int main()
      {
          blk b[2];
          for (size_t i = 0; i < 16; i++) {
              b[0].a[i] = i;
          }
          printf("normal  : %lu\n", b[1].a[2]);
          printf("overflow: %lu\n", b[0].a[10]); // undefined

          return 0;
      }

Depending on optimisations and compilers, you won't get the same result every time, and all sanitizers warn you about the UB. Conclusion: you can't assume a flat memory model, even on modern X86 in 32 or 64 bit mode. There are exceptions, depending on how you access memory, through which pointer. Again, your language specs just got longer for not defining what happens outside the bounds.

\---

Undefined behaviour simplified _one_ thing: the compilers themselves. At least, until they got the idea to use UB for optimisation, and started to summon the Nasal Demons as a result.

<comment><USER17> > Classic example of illusion of simplicity: signed integer overflow. Going > outside the range? Undefined. Left shifting a negative integer? undefined. > You can't just assume 2's complement, you have to be aware of the Nasal > Demons compilers are becoming increasingly apt at summoning.

I don't see this as an example of illusion of simplicity. On the contrary. Specifying exactly what must happen on integer overflow or left shift is almost always going to require more than saying "the behavior is undefined." Especially so if you try to keep it portable and allow different behaviors that are natural for different systems. And it probably won't help you if you're trying to write portable code, because now you need to worry about all the _defined behavior that might not be what you want._

 _If you want portable code, then you shouldn 't be able to assume a specific behavior, and if you want a language standard that enables the language to perform well across dislike platforms, you can't dictate specific behavior._

If you don't care about portability, you're free to enter a contract between you and your platform & compiler. For example, use -fwrapv. The standard doesn't forbid such a thing. By keeping things simple and leaving them undefined, it explicitly enables you to do things like this without violating what's defined in the standard.

> Another one: out of bounds array index is undefined, even if there was > something of the right type there:

That's a very specific scenario. In a lot of cases, there are arrays whose indexes are not right there, not constants (would require range analysis), or array size is not known (but maybe could be inferred). So the standard would have to become more complex in order to specify that something specific must happen in the special case that you're indexing into an array of known size in scope, with a constant index. By simply making out of bounds access undefined, they cover _all cases_ of array access in one short sentence.

Luckily, again, since the standard doesn't require any specific behavior, your friendly implementation is free to invent its own specific behavior, for example issue a diagnostic and return an error code because it saw that you were indexing out of bounds.

> Again, your language specs just got longer for not defining what happens > outside the bounds.

Why don't you show how to make the spec shorter by defining exactly what happens in this specific case? Remember that the spec still has to cover other cases, so you can't just delete all the text. You have to add a new case! Post a diff.

<comment> loup-vaillant _Integers represent the binary field of integers modulo 2^b, where b is the width of the integer. For signed integers, any value v >= 2^(b-1) is interpreted as being v-2^b instead._

That's how you specify "exactly what must happen on integer overflow". You thought I would have to take every undefined special case one by one and define them? That's naïve.

A similar argument can be made for pointers: _pointers are integers that represent memory addresses. Dereferencing a pointer to an allocated region gives you the value stored in that region (insert casts, uninitialised values, trap representations etc here). Dereferencing a pointer to a region that is not currently allocated is undefined._

And voilà, we no longer care _how_ a pointer was constructed then dereferenced, we only care about the address, and whether it pointed to an allocated region (and initialised with a compatible type etc, though that part could also be simplified).

> _That 's a very specific scenario._

I'm currently reporting a bug in the Libsodium cryptographic library because its Scrypt implementation (password hash by Colin Percival) has precisely this bug. My guess is that Colin was a _little_ too clever there, and treated C as a lower level language than it actually is.

A very specific scenario that may be, but it's a scenario we do encounter in real life.

<comment><USER17> > That's how you specify "exactly what must happen on integer overflow".

So yes, like I said, you can _force_ a particular behavior, and throw out any system for which that doesn't come naturally - you just made the language more complex for them. And no, that is not simpler than "the behavior is undefined", just different (and more imposing).

> And voilà, we no longer care how a pointer was constructed then > dereferenced, we only care about the address, and whether it pointed to an > allocated region (and initialised with a compatible type etc, though that > part could also be simplified).

Eh. You did nothing about undefined behavior. It's still there.

> A very specific scenario that may be, but it's a scenario we do encounter in > real life.

So what was your proposal that doesn't make the language more complex? Because above, you just gave us undefined behavior, which is our starting square.

<comment> loup-vaillant > _So yes, like I said, you can force a particular behavior, and throw out any > system for which that doesn 't come naturally_

Find me _one_ system in current use (2020) that isn't 2's complement.

> _you just made the language more complex for them._

Ah, but I was never talking about implementation complexity. I was talking about _specification_ complexity. Imposing 2's complement makes the specification simpler. No special case, no boundary. Just a binary field. Undefined behaviour draws such a boundary. An extra detail to specify and remember. Some thing that reminds you you're not _quite_ doing modular arithmetic.

> _Eh. You did nothing about undefined behavior. It 's still there._

I did. There's less of it. I've filled the bug, here's what's this about: [https://github.com/jedisct1/libsodium/issues/937](https://github.com/jedisct1/libsodium/issues/937)

Here's the relevant quote from annex J of the (heavy, I have printed it) C99 specifications:

 _Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object. (6.5.6)_

That's what caused the bug: we were taking a pointer from an array, then used it to overflow past it. It didn't matter that we could access the memory there. What mattered is that we locally overflew that array. Had we computed the pointer by first working with the _outer_ array, then pointed to the right element, we'd have the same pointer, except this time it wouldn't be undefined.

Bonus note: you don't even have to dereference the pointer, computing its value is enough to trigger undefined behaviour.

Here is some more undefined behaviour I have removed (it's subtle, relatively few programmers know this):

 _Pointers that do not point into, or just beyond, the same array object are subtracted. (6.5.6)_

There go flat memory models. Though to be honest, even segmented memory models could define that. Just make the subtraction already, it doesn't have to _mean_ anything. Make it unspecified or implementation defined at least.

 _Pointers that do not point to the same aggregate or union (nor just beyond the same array object) are compared using relational operators (6.5.8)_

That's the reason we can't implement memmove() portably and efficiently. And depending which tool you ask, even converting the pointers to intptr_t first isn't enough. Real world example here: [https://github.com/jedisct1/libsodium/commit/e7e378fad116c18...](https://github.com/jedisct1/libsodium/commit/e7e378fad116c18c78274e9b268acbd8a653268b)

\---

If you haven't already, go read the annex J from the C standard. Ponder the fact that compilers, unless you specifically ask not to (-fwrapv), will exploit every single one, _even on platform that could define some reasonable behaviour_ (2's complement machines). It may hint at how _hostile_ C is to programmers who care about correctness.

Believe me, I know. I wrote a whole Crypto library[1], and that's one of the _easiest_ things to get right, where C is concerned. I mean, the crypto itself is hard, but the total lack of dependency makes it pathologically easy to write in a portable way. Yet C still makes it hard.

[1] [https://monocypher.org](https://monocypher.org)

<comment><USER25> > Find me one system in current use (2020) that isn't 2's complement.

Fortunately, C2x will stop with the meme assumption that two's complement hasn't taken over the world (see draft N2479). It will not, however, specify signed integer overflow, which remains UB. :^)

<comment> loup-vaillant Compiler writers are too hooked on loop optimisations now to give up on undefined signed overflow. I'm afraid the only clean fix is to augment the language with an _actual_ `for` loop, with an immutable loop index and well defined start and finish values. Stuff like:

      for (size_t i : 0..10)     {} // Will go from 0 to 9 included.
      for (size_t i : 10..0, -1) {} // Will go from 10 to 1 included...
                                    // ...or maybe from 9 to 0 included?
                                    // Not sure which is best.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER26> Could we have a discussion about C without making it about Rust? The author doesn't mention Rust once.

</comment><comment><USER27> That does give some food for thought. Of all the new language features, the elements I really need —functors, asynchronous syntactical sugar, and static null analysis— don't require much of the bloat found in many modern languages.

</comment><comment><USER28> I assume that since he's writing a game, he's using some kind of library/engine/framework, but doesn't specify which one. This would affect his arguments for reliability (is the framework available on all these platforms?) and simplicity (how simple is the framework?).

Maybe he's only writing an ascii game though.

<comment><USER29> SDL is a common one, and is really easy to use

</comment></comment><comment><USER30> Random note: every few years I update a list [0] of popular programming subreddits (by subscriber count) on the /r/programming wiki. Over the last two years, C increased in popularity overtaking Ruby. And C++ increased in popularity overtaking PHP.

Rust, TypeScript, and Dart made big gains as might be expected. Swift didn't really move anywhere.

The biggest surprise for me were how much the interest in C and C++ continues to grow relative to other high-level languages (that probably also have greater number of professional users).

[0] [https://www.reddit.com/r/programming/wiki/faq?v=0692c0d1-617...](https://www.reddit.com/r/programming/wiki/faq?v=0692c0d1-6174-11ea-98bc-0e55b58028a7&v2=1063c806-621f-11ea-8159-0e437a1ed589)

</comment><comment><USER31> > Languages, especially dynamic ones and their runtime environments come and > go like fashion.

Sage advice.

<comment><USER32> Hardly, Ruby is 25 years old, Python is 30, Javascript is 24.

<comment><USER33> Well, Ruby is waning, Python is surging, and JavaScript is peaking. How will this look in 5 years? How about 10 years?

Would you say PHP is in fashion? How about Perl or Tcl?

<comment><USER34> Who cares about fashion? In 15 years Ruby, Python, JavaScript, Perl, TCL (particularly for building simplistic but effective GUIs), and PHP will all not only be usable, but actively used.

<comment><USER33> This thread is about fashion.

Did you read what the OP quoted? Here it is:

> Languages, especially dynamic ones and their runtime environments come and > go like fashion.

<comment><USER28> He's talking about languages coming on going. "Languages, especially dynamic ones and their runtime environments come and go like fashion. __When your target platform suddenly gets deprecated from the runtime you're relying on, well then you're just fucked and out of luck. __"

</comment></comment></comment></comment></comment></comment><comment><AUTHOR> The article without Medium paywall: [https://hownot2code.com/2020/03/13/why- im-using-c/](https://hownot2code.com/2020/03/13/why-im-using-c/)

</comment><comment><USER35> > For example; I doubt I'll ever be reaching for C when writing a web service > simply because the ecosystem around that domain isn't great and I'm not > itching to write my http framework at this time.

C has everything, including several top quality http frameworks. I use [https://github.com/corvusoft/restbed](https://github.com/corvusoft/restbed) and find it more reliable, more performant, and "better" in all respects than the php, js, node, and whatever frameworks I've been forced to learn.

<comment><USER36> I have programmed in C for a long time (for embedded before everything became ARM+Linux), and unless you have technical reasons to use C for a new project, I would skip it. I like tinkering with the low-levelness of C, but what applications really need that these days unless you're working with hardware/os level stuff?

There's also so much FUD about performance, but reality is that without numbers, you'll never know. Certainly for game development, unless you're working on a cutting-edge game engine, there's little reason to focus on performance first, and even then - most popular modern game engines offer interpreted paths for game logic.

Fear of garbage collectors is also bullshit in most cases. Many don't realise a simple call to free or malloc (or new/delete in C++) can result in just as much unpredictable hick-ups, which is why many games engines use specially tuned memory managers, some even specifically including garbage collectors (see the Unreal Engine for example).

Certainly in game development, flexibility to tune game mechanics is far more important to make a good game than performance, and creating such flexibility in a C application is a lot more complex/more work than in a higher-level language, and you'll end up building very high walls you really don't want to tear down and start over with.

<comment><USER35> The thing I find interesting about C is that everything and anything done in other languages can be done in C; after all, how does that language implement feature X? In some low level manner, and that is where C shines. C is not just the language, it is the entire ecosystem of all available source code written in C - compilers, browsers, you name it, it is there. Working in C is as much research and integration as one wants, with the results being any flavor of programming style you want - with all the foundation bits under your complete control. Plus the community of pure C developers is people that have been working in it for decades, with more practical programming wisdom than you'll find in shops with teams of high level developers releasing modern applications. The C teams release them too, but theirs is exponentially higher performance in exponentially smaller foot prints. Lots of software shops appear to be more into empire creation than quality software, but that's a result of decades of software industry propaganda too.

<comment><USER36> > The thing I find interesting about C is that everything and anything done in > other languages can be done in C

With emphasis on "can". Not that you should. This is exactly what I mean, in many cases it's interesting for an intellectual exercise, but I would avoid it for new projects unless I really can't.

</comment></comment></comment></comment><comment><USER37> C, besides its intrinsic beauty, does not fill you with the urge to tell others to pipe curl output into their shell; that's a win for me.

</comment><comment><USER38> i use c in scientific computing for small processor intensive routines that can leverage openmp's straightforward parallelism.

<comment><USER39> Have you considered using `phtreads`? It's part of the POSIX standard, and it's less cumbersome to use.

</comment></comment><comment><USER28> I agree with all his arguments, as long as I'm only writing HelloWorld.c :o

</comment><comment><USER29> I like working with C. It's simple and transparent. I wish I could use it more.

</comment><comment><USER40> Nothing new really

<comment><USER41> You would have been better off writting that in rust</comment></comment>


Different Ways to Create Arrays in JavaScript - <AUTHOR> https://time2hack.com/different-ways-to-create-arrays-in-javascript/ <comment><AUTHOR> Any other way that you know and wanna share with others?</comment>


Glnk.it - a location based URL shortener - robert-boehnke http://glnk.it/

<comment><AUTHOR> This sounds awesome, but would be better with a demo so I don't have to login with Facebook.

<comment> robert-boehnke This will redirect you to the wikipedia article of your country <http://glnk.it/1u>

(I only added a few and chose a fallback for the rest of the world)</comment></comment>


You should learn regex - <AUTHOR> https://blog.patricktriest.com/you-should-learn-regex/ <comment><USER2> Your e-mail validation regexp is broken. It allows spaces in the domain name, among other things. And the other one is overly complicated (there are totally unnecessary fragments). Also, you don't state what flavour of regexp it is.</comment>


Janus Privacy Adapter - plug this in and anonymize your web traffic - <AUTHOR> http://paulstamatiou.com/2008/12/24/anonymize-your-web-traffic-with-januspa

<comment><AUTHOR> for some value of anonymous, via Tor network

</comment><comment><USER2> I wouldn't count on this being next years runaway success. Cool though.

<comment><AUTHOR> might be popular in Australia depending on what happens to that legislation to monitor everyone's traffic or whatever it was..

</comment></comment><comment><USER3> What's the advantage of doing it in hardware instead of software?

<comment><USER4> It would depend.

This is the easiest way to do it for a network of computers without client side setup. Another alternative would be to set up a server which does it for you.

Let's say you're having a meeting with dissident bloggers in your house in china, and you would like to provide a wireless network for them. The safe and easy way to do it would be to patch one one these between you router and acces point.

Instant anonymity.

<comment><USER3> True, true.</comment></comment></comment>


Firefox 2012 Roadmap published - <AUTHOR> https://wiki.mozilla.org/Firefox/Roadmap <comment><USER2> There's one thing I don't understand of Firefox's current evolution: developer tools.

Firefox already has an absolutely excellent (third-party driven) devtool, at the root of basically all modern (browser) devtools, in Firebug. Firebug is pretty much the source of Webkit's Developer Tools (Safari and Chrome), of Drosera (Opera) and even of the utter dreck that are MSIE8+'s builtin developer tools, and one of Firefox's greatest gifts to web development (along with taking down MSIE and the idea that following standards might be a good idea from time to time)

It's not perfect by a long shot and it does have issues (which get addressed over time), but it's there and more importantly its _good_.

Yet they are reimplementing it bit by bit, in a less-integrated, less practical, and overall shittier way.

Why?

Why is mozilla wasting time on that?

Why couldn't they instead focus on making _Firebug_ better and providing a better, deeper integration between Firefox and Firebug? Or by developing new API and panes trailblazed by the Webkit devtools (e.g. rendering timeline)? In fact, why not look into merging Firebug into Firefox pretty directly (disabled by default of course)?

Does anybody know? Because it boggles my mind, Firebug has had a complete console for ages and Firefox 9 added a shitty one (which mostly spends its time being spammed by irrelevant garbage due to not having a network tab) as a "quake console" (opens from the top), and Firebug has had an (excellent) DOM inspector for ages (again) and Firefox 10 adds a completely shitty one[0]... but at the bottom of the window so using both the inspector and the console takes twice as much visual space, and if you open the "styles" pane your visual space shrinks down to a postcard.

Please help, because they've lost me completely with that strategy.

[0] seriously, can't create new attributes, can't add content to an empty one (can only change existing non-empty content), pointlessly huge breadcrumb trail, blue-on-black theming which looks completely out of place, no autocompletion of CSS properties, no hyperlinking of CSS files or elements, no layout display, no object inspection, no DOM changes breakpoints, no HTML edition, no separate window, what's there is barely useful, we're talking IE8-level of functionality (of the inspector tab, IE8's devtools at least have a debugger) if even that (thought hopefully not as terminally buggy) and I'm probably forgetting half of it

<comment><USER3> There are some pretty strong fundamental reasons why you want to have debugging tools be exactly in sync with releases, especially when you are making major changes to feature support and rendering. Also, in this day it just makes sense to have such tools integrated in the browser.

Now, the Firefox team might not be pulling off the execution very well (though it's a little unfair to compare an early generation product to a more evolved product) but I think it's probably the right decision for the future, hopefully they'll iterate on it enough to get it into a good state.

However, all of this is sort of beside the point. The Firebug lead went to go work for the Chrome team, so the Firefox team is in a bit of a pickle.

<comment><USER2> > There are some pretty strong fundamental reasons why you want to have > debugging tools be exactly in sync with releases, especially when you are > making major changes to feature support and rendering. Also, in this day it > just makes sense to have such tools integrated in the browser.

That's cool and I can see that, but it does not explain why they're not building on Firebug's established base.

> However, all of this is sort of beside the point. The Firebug lead went to > go work for the Chrome team, so the Firefox team is in a bit of a pickle.

Firebug already survived the departure of its founder years ago, if there's a will it can survive Barton's as well.

<comment><USER3> As I understand it there are limitations to the way firebug (as an extension) works that would make continued development and adding new features problematic. I don't know enough about Firefox's dev tools work to say whether or not it even makes sense to make use of firebug's code base and whether or not that sort of thing will happen in the future. It would be a huge failure if the firefox devs couldn't even manage to match the functionality of firebug, but it's more than a little too early to say that that will be the case.

As to the development team, there's a difference between surviving and thriving. Especially as the pace of firefox development has been accelerating I think bringing dev tool support in house is the only rational choice.

</comment></comment></comment></comment><comment><USER4> _Firefox Hotfix: There are small issues that can occasionally affect Firefox users after a release. Correcting those small issues should not require a full Firefox update. With a new hotfix system, Mozilla can patch minor issues in Firefox without requiring a browser restart._

This is great.

<comment><USER5> That's just the first part; in Q2 there's:

 _Silent Update: The Firefox update process will be moved to the background and Windows admin passwords and/or UAC prompts will be removed. Also, users with the rare incompatible extension will have a gentler upgrade process._

<comment><USER6> I can't help but think that requiring a prompt to modify Firefox binaries is a good thing.

<comment><USER7> Do you think this is a good idea for Windows updates for the big public? If not, how is Firefox different?

Firefox installers are signed (and so are updates), so I don't see any security issues here. On the contrary, removing the need for people to approve all those useless UAC prompts makes it more likely they will actually look at the next one to pop up and see if it is legit.

<comment><USER8> Is there an issue with mitm attacks at hostile wifi points of access? Dns pointing to a bunk certificate authority maybe? I am not fully versed on this though so I don't know how possible this attack is.

<comment><USER9> The update payload itself is signed with a private key controlled directly by Mozilla, to avoid vulnerability to CA compromises [1]. The connection to the update server performs additional checks to ensure not only that the SSL certificate is valid, but that it matches one of a small list of known certs or issuers, so that a fraudulent CA can't hijack the connection with a forged certificate [2][3].

[1]: [https://wiki.mozilla.org/Security/Reviews/Firefox10/SilentUp...](https://wiki.mozilla.org/Security/Reviews/Firefox10/SilentUpdateOSDialogs)

[2]: <https://bugzilla.mozilla.org/show_bug.cgi?id=544442#c24>

[3]: <https://bugzilla.mozilla.org/show_bug.cgi?id=583678>

(As a side note, the fact that this is necessary points out some of the major risks in the current CA system, which will hopefully be addressed in whatever eventually replaces it...)

</comment></comment></comment></comment></comment></comment><comment><USER10> > Based on the Verified Email standard, Firefox users will be able to log in > to Firefox to enable Sync and user-centric site logins. Users will finally > be able to say goodbye to remembering countless passwords.

This! It would be great if Firefox could automatically log you into websites you already are registered on and have associated with your FF login.

<comment><USER11> That's indeed the promise of BrowserID. Learn more at <https://browserid.org/>

It's already being used for sign-in at <https://developer.mozilla.org/>, and it will only get better once browsers and identity providers ship native support.

</comment></comment><comment><USER4> Off topic (somewhat)... I have also been using the latest Firefox Mobile nightlies on my tablet... wow. It's responsive, it's slick, it's fast... it's buggy... (it's a nightly). It's also a sign of brilliant things to come from Mozilla this year. I can't wait for the current Mobile nightlies to hit open release.

<comment><USER12> The release versions of Firefox Mobile were good enough to be the default browser on my 7" HTC Flyer tablet, but don't seem to handle the bigger resolution of Transformer Prime that well (lots of screen flickering when scrolling).

I just tried their Aurora nightly, and there things were quite smooth. Not yet Chrome-on-Android smooth, but getting there.

As always, Firefox Sync is the killer feature on mobile.

<comment><USER13> I work on Firefox Mobile. What in particular made you feel that Aurora was less smooth than Chrome?

<comment><USER12> I still see a lot of areas in the process of being redrawn while I scroll.

A lot better than "this process is frozen, Kill?" that I get with Browser, though.

I didn't check yet with Aurora, but do you handle keyboard shortcuts? One thing that keeps me with Browser instead of Chrome is that it supports desktop-style shortcuts like Ctrl-L and Ctrl-R when I'm using the hardware keyboard.

<comment><USER4> Oh yes! Strong second for keyboard support in Firefox Mobile. I have an ASUS Slider, also with a hardware keyboard, and I keep wanting to go back to the keyboard when browsing. I know it's not common on tablets but when you do have a keyboard attached (or built in) it's great to have.

<comment><USER12> Ok, verified that the shortcuts indeed don't work in Aurora and filed a bug: <https://bugzilla.mozilla.org/show_bug.cgi?id=726716>

Please add comments there if you have any.

</comment></comment></comment></comment></comment></comment><comment><USER14> I really think Firefox should have nailed down addon compatibility and silent updates before embarking of this FF4+ versioning adventure. It's good to see that they are both on the roadmap, but I fear it's too little too late.

<comment><USER15> As far as I understand it, they did largely nail down addon compatibility at least around the same time as the rapid releases began. Addons hosted on addons.mozilla.org have since last April [1] got automatic compatibility bumps each time a new version of Firefox is released.

What they didn't realise was that only 25% of addons in active use were hosted on AMO, and the vast majority were self-hosted. The change referred to in this roadmap is to make the browser itself (rather than just AMO) treat extensions as compatible by default (and presumably quite a lot of supporting work to make sure that's a responsible way for the browser to behave). That change has also now landed [2].

These are important problems to tackle, but we should give credit where it's due, and it's rather more than just "on the roadmap". Justin Scott gives a good overview of their thought process and actions taken: [3]

[1] [http://blog.mozilla.com/addons/2011/04/19/add-on- compatibili...](http://blog.mozilla.com/addons/2011/04/19/add-on- compatibility-rapid-releases/) [2] <http://www.mozilla.org/en- US/firefox/10.0/releasenotes/> [3] [http://blog.fligtar.com/2011/09/26/add-on- compatibility-prog...](http://blog.fligtar.com/2011/09/26/add-on- compatibility-progress-plans/#more-1246)

</comment></comment><comment><USER16> Add-on performance indicators would be awesome. I'm looking forward to addon syncing too.

<comment><USER17> I recently read about a Mozilla authored extension that gives you more performance insight. I think some features only work with special FF builds right now, though. :)

[http://www.visophyte.org/blog/2012/02/04/aboutnosy-is- aboutm...](http://www.visophyte.org/blog/2012/02/04/aboutnosy-is-aboutmemory- with-charts-helps-you-lay-blame-more-easily/)

</comment></comment><comment><USER18> > _The Firefox update process will be moved to the background and Windows > admin passwords and/or UAC prompts will be removed._

Oh, God, no. If Chrome does it this way, it is not a reason to blindly copy the idea. Why the hell would I want another privileged process running on my machine?

<comment><USER7> Because it's the best solution to deal with the problem at hand (updating another process's .exe without requiring an UAC prompt). Google and Mozilla aren't idiots, you know. Internet Explorer can circumvent this due to being able to use Windows Update. Safari and Opera (AFAIK) don't do rapid release.

<comment><USER18> Well, no, it is _not_ the best solution by a wide margin.

There is no reason Firefox has to go into a _system_ ProgramFiles directory when it is installed by a user. It needs to go into the _user's_ ProgramFiles. If it is installed by an admin, then, yes, it should go into the system directory, and it is reasonable to have the updater process run as a system service. But if it's me, Joe User, installing Firefox on a shared box for my own use, then (a) I should really be able to do that within the confines of my account permissions (b) the updating mechanism should also fit into the same set of restrictions.

Just think about it for a minute.

PS. "Google and Mozilla aren't idiots" is not an argument. Microsoft aren't idiots either, but look at Vista.

<comment><USER7> But Firefox _already works like that_. If you install as a (non-admin) user, it goes into your user dir and there is no update service.

If you install as an admin user, it goes into Program Files, and by your own admission, there's no other way to update it than to have the update service.

</comment></comment></comment></comment><comment><USER19> The new "Australis" theme (on the roadmap for 2H) looks like Mozilla is trying to copy Chrome yet again. Don't get me wrong, Chrome does a lot of things right, but shouldn't a browser have some sort of... unique visual identity?

[http://people.mozilla.com/~shorlander/firefox-ui- design/fire...](http://people.mozilla.com/~shorlander/firefox-ui- design/firefox-visual-design-across-platforms.html)

<comment><USER20> There's a push towards minimalism by all the browsers and there is only a few ways to do a minimal browser UI.

<comment><USER7> True. Merging the search box and urlbar is a logical step. I was worried at first at blurring the distinction between "search in my local bookmarks/history" and "send to Google", but if it works like in the mobile browsers than I might be able to live with it (show local results and offer "search on google" as an option). But I wonder how usable that would be with many search engines.

Don't like:

\- The Firefox menu at the top of the window is moved to a Chrome-style settings menu on the right. Yet, no vertical screen estate was won. (I realize why this is: the top must remain free to make the window draggable, but it also shows how pointless moving it was, as you've now lost horizontal estate for no gain)

Makes sense:

\- Home button replaced by home pinned tab. \- New downloads UI. Prior to 4.0 I used an extension that showed something similar to what you see in those screens.

<comment><USER21> Regarding the menu, no vertical space may have been won, but definitely a bit of horizontal -- it looks like there's enough room for an additional tab there now, which is nice. (maximized on 1366*768, it's rare that I never have tab overflow)

<comment><USER22> If you often run out of tab space, reduce the minimal width of tabs. I don't quite remember the exact variable in about:config but I was always able to find it (search for width probably). One of the first things I had to set when I was using Firefox as my secondary browser. It was 3.x but I don't think they would remove the little configuration they offered.

<comment><USER21> It looks like they did: <https://bugzilla.mozilla.org/show_bug.cgi?id=574654>

Someone did package up the CSS and put it into an addon though: [https://addons.mozilla.org/en-US/firefox/addon/custom-tab- wi...](https://addons.mozilla.org/en-US/firefox/addon/custom-tab-width/)

<comment><USER23> Tab Mix Plus is great for all sorts of tab settings.

<https://addons.mozilla.org/en-US/firefox/addon/tab-mix-plus/>

</comment></comment></comment></comment></comment></comment></comment><comment><USER24> I would love to try it when it reaches version 20.0.

</comment><comment><USER25> No mention of OS X Lion on the roadmap makes me sad.

</comment><comment> iso8859-1 List of stuff already in Chrome:

\- Inline PDF View

\- In-line Preferences Manager

\- Network Installer

\- Integrated translation service

\- Silent Update

Anything else?

<comment><USER26> Did Chrome ever use anything like pdf.js?

<comment><USER27> My understanding is that Google licensed the FoxIt PDF viewing engine to embed into their Chrome binaries. It probably isn't available in the open-source Chromium.

<comment><USER28> I can confirm it isn't.

<comment><USER26> In KDE at least, KParts Firefox plugin does a very good job for PDF viewing, using Okular.</comment></comment></comment></comment></comment>


Cracking Passwords in the Cloud: Breaking PGP on EC2 with EDPR - <AUTHOR> http://news.electricalchemy.net/2009/10/cracking-passwords-in-cloud.html

<comment><USER2> This isn't "breaking PGP", it's guessing PGP passphrases. If they had guesses a PGP _key_ using a cluster of virtual machines, that would be news.

<comment><USER3> _it's guessing PGP passphrases_

Also, if you can brute-force a PGP passphrase using a cluster of EC2 instances, it's trivial to brute-force it in hardware (using FPGAs or, ideally, ASICs).

If you want to protect something with a passphrase, use scrypt!

<comment><USER2> No matter how you hash them, passphrases are still pretty secure. If you can type your PGP passphrase very quickly, you're doing it wrong.

<comment><USER3> _passphrases are still pretty secure_

... at least until someone comes along with a microphone (or a cell phone) and exploits the acoustic side channel. :-)

</comment></comment></comment></comment><comment><USER4> The passphrase is the weak point in PGP. I suppose some people treat it like a password, which is the wrong approach. It should be much longer and harder than a normal password.

Their analysis does demonstrate how cost-effective it has become to crack low- complexity passwords.

</comment><comment><USER5> They would also need a way to validate the data unless the encryption was symmetric, I don't think they have tested this out on data they didn't already have.

<comment><USER6> They were brute-forcing a PGP-encrypted ZIP archive, which would have been symmetric encryption.

These kinds of archives were produced by the PGP Desktop application (at least in earlier versions; I don't know if it still does) and were functionally similar to using "gpg -c", although the actual file format is/was different and incompatible.

Had the guy used a public/private keypair for encryption rather than a password, I suspect the work needed to bruteforce it would be much greater. But that doesn't look like the situation.</comment></comment>


Kids Apps on Google Play Have "Disturbing" Content and May Violate Privacy Laws - <AUTHOR> https://www.buzzfeednews.com/article/virginiahughes/google-android-kids-apps-deceptive-ads <comment><USER2> Link to letter sent to the FTC [PDF]: [https://www.commercialfreechildhood.org/sites/default/files/...](https://www.commercialfreechildhood.org/sites/default/files/devel- generate/vad/google_ftc_complaint.pdf)</comment>


Building Teams Using Quantitative Analysis in the NBA – The Last Rites - <AUTHOR> http://blogmaverick.com/2010/10/03/building-teams-using-quantitative-analysis-in-the-nba-the-last-rites/

<comment><USER2> Bill Parcells always talks about determining where football ranks as a priority for his players.

It doesn't have to be the top priority but it better be near the very top (family, faith would be considered acceptable 'higher priorities'). He wants players with similar life priorities.

Bill Belichick has a special assistant (his name escapes me), a football lifer, that solely focuses on assessing the make up of players.

That said, the simple fact is that the very best GM's in pro sports know how to sort through the statistics and find the die-hard competitors. Statistics matter but only when coupled with the right make up.</comment>


Ask HN: Popularity of Unicode Versions of URLs? - <AUTHOR> When I look at web marketing data (e.g., Alexa), I only ever see results for URLs with Latin-based URLs, even for regions with non-Latin alphabets.  Do users from places with non-Latin alphabets type in Latin website names, or do they use non-Unicode versions?<p>I know China likes to use numerical URLs, which avoids this problem, but what about other places? <comment><USER2> There's a solution but it's awkward. We scandinavians use æøå but rarely do we use them in URIs. Like the electronics chain "Elkjøp" uses "elkjop.no" \- this is coincidentally one of the few that has actually registered "elkjøp.no".

I have "kråke.re" myself but the DNS entry is really xn--krke-roa.re because international character DNS is an ugly, ugly hack.

<comment><AUTHOR> Very interesting. Is it easy to type this special characters on your mobile?

That encoding is punycode, right?

<comment> Lorenz-Kraft I think all modern mobil keyboards show the regularly used chars depending on your language. So its very easy.

I think the punnycode encoding is just used for the domains, but not for the urls. The urls should be normal utf-8 encoding. Wonder why they made a difference at all.

</comment></comment></comment><comment> Lorenz-Kraft i once tried the unicode urls and they are a pain in the a§§ because some browser (and mail clients) interpret them differently. Also some search engines and/or crawlers interpret them different (mostly they are double encoded). This in turn results in several "errors" that the developer then has to re- en/decode again server side to serve the correct content to url.

On the other side: Just "transliterate" a url is super simple and people all over the world can at least read the url (and probably memorise). For example: ä => ae => everybody in Germany knows how to read and interpret this.

SEO wise: No difference at all.

</comment><comment><USER3> I believe because of Cyrillic URL spoofing from a about 10-15 years ago most people stay away from UNICODE urls. China's numeric URL's maybe so that tracking URL's are easier, but that's just a guess.</comment>


Knowing when to quit - an under-rated skill. - <AUTHOR> http://www.freakonomics.com/2011/09/30/the-upside-of-quitting-full-transcript/ <comment><USER2> tl;dr is in the one-to-last paragraph:

 _"A quitter never wins and a winner never quits." In 1937, a self-help pundit named Napoleon Hill included that phrase in his very popular book Think and Grow Rich. Hill was inspired in part by the rags-to-riches industrialist Andrew Carnegie. These days the phrase is often attributed to Vince Lombardi, the legendarily tough football coach. What a lineage! And it does make a lot of sense, doesn't it? Of course it takes tremendous amounts of time and effort and, for lack of a more scientific word, stick-to-itiveness, to make any real progress in the world. But time and effort and even stick-to-itiveness are not in infinite supply. Remember the opportunity cost: every hour, every ounce of effort you spend here cannot be spent there. So let me counter Napoleon Hill's phrase with another one, certainly not as well known. It's something that Stella Adler, the great acting coach, used to say: Your choice is your talent. So choosing the right path, the right project, the right job or passion or religion — that's where the treasure lies; that's where the value lies. So if you realize that you've made a wrong choice — even if already you've sunk way too much cost into it — well, I've got one word to say to you, my friend. Quit._

<comment><USER3> There's a difference between "quitting" and "putting your energy elsewhere". The second is a good thing, the first is just giving up.

<comment><USER4> Yeah, the article addressed that pretty well:

VENKATESH: _So one of the strange things we found out when we spoke to baseball players is that they have their own language for quitting. They actually quit. They just don't call it that. They don't call it quitting. They don't call it giving up. But, they say, "You know what? I'm just going to shut it down for a while."_

VENKATESH: _So, what does it mean to be a quitter as opposed to a "shutter downer"?_

HALL: _Probably the same thing, is just sounds better when you say 'I'm just shutting down.' You know, it's like you're not really doing it, but, you know, you are._

</comment></comment></comment><comment><USER5> Seth Godin's "The Dip" talks about this and knowing the difference between a dip and a cul-de-sac.

<comment><USER6> Agreed. "The-Dip" is a great read on this topic. His basic premise is great in the sense that it's not about quitting or sticking into something for sake of stubbornness.

It's all about _knowing_ what It'll take to quit before hand, see if it's worth starting, and improve the odds of making it past the dip.

</comment></comment><comment><USER7> Unfortunately I had to quit the article about halfway through. It being a transcript of a radio broadcast made it pretty hard to follow, at least for me, but what I read was pretty fascinating, especially the part about the baseball player.

Does anyone know if there's a version of this that is formatted as a article?

<comment><USER8> Link to their podcast -- more enjoyable than reading a transcript.

[http://itunes.apple.com/au/podcast/freakonomics- radio/id3546...](http://itunes.apple.com/au/podcast/freakonomics- radio/id354668519)

</comment></comment><comment><USER9> From the examples, it sounds like the answer to the question "when should I quit" comes most easily when you have some source of objectivity.

It's easy, from the outside, to see a baseball minor league player in their early 30s and think "he would be better off quitting." The hard part is to accept that idea from the inside. Sometimes having a dream to be striving for is nearly as rewarding as success itself.

<comment><USER10> This reminds me of Rickey Henderson, who played for 25 seasons, played minor league ball when he was 48 and still refuses to retire.

</comment></comment><comment><USER11> I listened to this over the weekend. It was entertaining, but can be summed up with "Sometimes you quit too early, sometimes you quit too late" from somewhere in the middle of the program.

Not a lot of hard data, but some interesting anecdotes.

</comment><comment><USER12> The podcast also highlighted the importance of "failing fast," or figuring out what will or will not work as soon as possible, and adjusting accordingly. This iterative approach to finding success seems to pervade start-up culture, and in my instances, is very sound advice IMHO.

</comment><comment><USER13> I hate the word "pivot" because it's over-abused in startup parlance, but I like it as a way to describe smart navigating -- not just in startups per say, but maybe also in the bigger game of life as well.

I think it's important to remain focused on one big long-term destination/path, but still be flexible to "quit" short-term and change directions along the way to eventually get there.

</comment><comment><USER5> "If at first you don't succeed, try, try again. Then quit. No use being a damn fool about it." \-- W.C. Fields

<comment><USER14> Can't remember the source ... "If at first you don't succeed, destroy all evidence that you ever tried."

<comment><USER15> Or just make it so banal on your resume no one will care to check.

"Tamed tigers for a circus" becomes "Shoveled cat poop".

</comment></comment></comment><comment><USER16> Here is the MP3: [http://audio.wnyc.org/freakonomics_specials/freakonomics_spe...](http://audio.wnyc.org/freakonomics_specials/freakonomics_specials060511.mp3)</comment>


How your history knowledge can save you money - <AUTHOR> https://medium.com/@tripdelta/how-your-history-knowledge-can-save-you-money-97e4df93598d <comment><USER2> Interesting stuff. Never thought of this. Will try this for my next trip.</comment>


Awesome-C: A curated list of awesome C frameworks, libraries, resources - <AUTHOR> https://notabug.org/koz.ross/awesome-c

<comment><USER2> > PCC - A very old C compiler.

"Venerable" would be a much more gracious way to describe the compiler that brought us so much, to say nothing about the fact that it's still actively maintained today.

</comment><comment><USER3> It seems that this list has a clear preference to GPLv3. There are tons of popular MIT and BSD libraries missing in each section.

<comment><USER4> If you know of such libraries, please open an issue on the awesome-c repo, and I will include them.

</comment></comment><comment><USER5> It's a bit off-topic, but is there a reason to still use the original MinGW and not MinGW-w64? The list only mentions the original one.

I also didn't know that GNU refers to the MIT license as Expat license.

The list also links to several PDF versions of books that are still sold and also not published under a free license. Just mentioning them should be fine. We all know how to use an online search engine if we want to get a copy, don't we?

<comment><USER4> No good reason for that - I don't use Windows, thus my omission. I'll correct it as soon as I can.

As for the PDF links - good point. I'll amend that too.

<comment><USER5> There also some tools I think should be added: I'm not sure if linking to AddressSanitizer is okay (as its (an underused) part of Clang and GCC), but I consider include-what-you-use, unifdef, and maybe C++ Compiler Explorer a worthwhile addition.

What about mbedTLS (formerly PolarSSL)? It's dual licensed though.

[https://code.google.com/p/address- sanitizer/(Apache](https://code.google.com/p/address-sanitizer/\(Apache) 2.0)

[https://code.google.com/p/include-what-you- use/](https://code.google.com/p/include-what-you-use/) (same license as LLVM/Clang)

[http://dotat.at/prog/unifdef/](http://dotat.at/prog/unifdef/) (BSD)

[http://gcc.godbolt.org/](http://gcc.godbolt.org/) (BSD)

[https://tls.mbed.org/](https://tls.mbed.org/) (GPLv2)

Edit: midipix is something one should look out for. What it promises to support and how, sounds much more appealing to me than Cygwin or MinGW-w64, but it's still in early development: [http://midipix.org/](http://midipix.org/)

</comment></comment></comment><comment><USER6> Don't forget ArnoldC :) [https://github.com/lhartikk/ArnoldC](https://github.com/lhartikk/ArnoldC)

</comment><comment><USER7> What are your thoughts on embedded scripting languages, for when your C needs a little more runtime flexibility? There are a few written in C and are designed to be slotted into a larger C program.

If you want to start a "computer vision" category, I've written a little library that might qualify: QuickBlob (LGPL connected component labeling)

<comment><USER8> I've worked with _a lot_ of these (I work in game development, where this sort of thing is fairly popular), and IMO they're not worth the significant runtime cost and software complexity required to integrate them.

In my experience, it's almost never that much harder to develop the code in C or C++ (especially given how much better C/C++ debuggers are from those found in scripting languages).

Most of the dynamism and flexibility that actually give you benefits (IMO module systems and hot code reloading -- the latter of which is actually easier to do in C than in a lot of other languages) can be achieved using dynamically linked libraries, anyway.

</comment></comment><comment><USER9> Lots of goodies in there. I'll make a pitch for including some modern mallocs like jemalloc or tcmalloc in the list. Also the hdf5 library for numerical data storage is quite useful (pytables is built on top of it).

<comment><USER4> Yeah, those are good suggestions - I'll add them.

</comment></comment><comment><USER10> Nice little list. Now all we need is something like 'CPM', the C Package Manager. Got to keep up with the cool kids.

</comment><comment><USER11> I am confused about notabug.org, why do the project and profile pages look eerily similar to GitHub's?

<comment><USER4> The whole point of NAB is to be a fully-free (as in freedom) alternative to GitHub. It was prompted (in a big way) by the acquisition of Gitorious.

<comment><USER12> Which is not an amazing reason to get into uncanny valley territory with respect to GitHub's design and page layout - to the point of using GitHub's Octicons (which is entirely permitted by the license, for the record, but IMO contributes to an overall uncomfortable feeling when combined with other aspects).

</comment></comment></comment><comment><USER13> libdjb is missing

<comment><USER4> Thanks - will add.</comment></comment>


Show HN: Node on Train – Step by step to create an application - <AUTHOR> http://nodeontrain.xyz <comment><USER2> > AngularJS is what HTML would have been, had it been designed for building > web-apps.

Please stahp</comment>