Ask HN: What book to read to get a footing in CS theory? - <AUTHOR> A friend of mine has just taught herself the basics of JavaScript then done a code boot camp. She's pretty comfortable writing code now, but hasn't had a chance to get to grips with stuff like complexity analysis yet.
It seems to me like she's a member of a large and growing target audience for a book that gets you started with all the stuff you would learn in a computer science degree, with the assumption that you already know how to express an algorithm as code.
Can anyone recommend such a book? <comment><USER2> Jeff Erickson's Algorithms text is a great resource: [http://jeffe.cs.illinois.edu/teaching/algorithms/](http://jeffe.cs.illinois.edu/teaching/algorithms/)

The entire book -- including the portions labeled Models of Computation, Director's cut, and Extended Dance Remix -- presents accessible introduction to much of the CS theory landscape.

Someone already praised the shorter book titled "Algorithms" by Dasgupta et al, and I second it. Tim Roughgarden's "Algorithms Illuminated" series is in this genre too.

I'd also recommend the MIT lecture notes on Mathematics for CS: [https://courses.csail.mit.edu/6.042/spring18/mcs.pdf](https://courses.csail.mit.edu/6.042/spring18/mcs.pdf) This is distinctive for its intuitive explanations with essential, approachable formalism. The exercises are fine too, if you are really mean it.

Sipser's book on the Theory of Computation is great and the one by Hopcroft et al is also very good (as suggested by others). But the most beginner-friendly (or, light on math) coverage of this area is apparently in Peter Linz's book "Introduction to Formal Languages and Automata". An alternative flavor in the treatment of much of the same topics is in this free book: [http://cs.brown.edu/people/jsavage/book/](http://cs.brown.edu/people/jsavage/book/)

<comment><USER3> +1 for Dasgupta (DPV). It is used at GT and Berkeley in CS.

[http://algorithmics.lsi.upc.edu/docs/Dasgupta- Papadimitriou-...](http://algorithmics.lsi.upc.edu/docs/Dasgupta- Papadimitriou-Vazirani.pdf)

<comment><USER4> Any solution manual?

</comment></comment></comment><comment><USER5> Go ahead and get your free copy of Avi Wigderson's Mathematics and Computation [https://www.math.ias.edu/avi/book](https://www.math.ias.edu/avi/book).

Broadly speaking there are two types of "CS Theory":

1\. "What is computation and what can be computed?" That's what Wigderson's book is about. Complexity theory.

2\. "What's the best way to compute something?" covered by "Introduction to Algorithms" and the like -- sth people ask on interview questions. In addition to the references here, [http://people.cs.uchicago.edu/~laci/17discrete/](http://people.cs.uchicago.edu/~laci/17discrete/) gives some good puzzles to work through.

<comment><USER6> Perfect answer, I second this.

<comment><USER7> A related reference, cited by this book, and a bit shorter and simpler is Garey & Johnson _Computers and Intractability_.

It's a really good classic little textbook.

</comment></comment></comment><comment><USER8> For CS theory, I would rather suggest you to focus on classic CS courses, here's my list:

0\. Do not touch "Introduction to Algorithms" until you are in a dream job.

1\. CS 61A: The Structure and Interpretation of Computer Programs [https://cs61a.org/](https://cs61a.org/)

2\. CS61B: Data Structures [http://datastructur.es/sp16/](http://datastructur.es/sp16/)

3\. Coursera: Princeton Algorithm [https://coursera.org/learn/algorithms- part1](https://coursera.org/learn/algorithms-part1)

4\. CMU 15213 CSAPP [https://courses.cs.washington.edu/courses/cse351/16sp/videos...](https://courses.cs.washington.edu/courses/cse351/16sp/videos.html)

5\. Keep moving.

<comment> non-entity > Do not touch "Introduction to Algorithms" until you are in a dream job

Any idea why? Its unlikely I'll ever land my "dream job" butnim curious as to the reasoning.

<comment><USER9> If by "Introduction to Algorithms" we mean the infamous book by Cormen et al...

When I propose to use it to prevent sea rise by drying the sea I only half jest. It's IMO one of the worst books to use except as reference when you already have a good grounding.

</comment></comment></comment><comment><USER10> [https://teachyourselfcs.com/](https://teachyourselfcs.com/)

<comment><USER11> Well this is superb. I've traditionally given my own piecemeal answer to the teach-myself-cs question, but I'll be handing this link out in future.

</comment></comment><comment><USER11> Skiena's Algorithm Design Manual:

[https://www.amazon.com/Algorithm-Design-Manual-Steven- Skiena...](https://www.amazon.com/Algorithm-Design-Manual-Steven- Skiena/dp/1849967202)

Far more readable than the usual text (Cormen), the first half is a guide on how to select and design algorithms for the problems you encounter, and the second half is a whistle-stop tour of hundreds of well-known algorithms. The tour helped me a lot with X->Y esque issues where I was building bad solutions because I didn't know anything better could exist.

Incidentally, there's a lot more to CS theory than algorithms and data structures, but if you're asking on HN for a generic CS theory book, I reckon it's most likely an algorithms and data structures book that you're after.

<comment><USER12> I'm going to disagree slightly with your choice (which was also my choice at first). While A.D.M. has all the topics you would be interested in, I think the book assumes that you have already groked the fundamentals behind, say, why a linked list is different from an array. For an absolute beginner, I would suggest the type of book that forces you to go through every step of deleting an item from a list, which is something Skiena's book (luckily) doesn't do. The book is great for learning new ways to think about problems, but IMHO a beginner should learn the basic ways first.

"Introduction to Algorithms" by CLRS seems to be the default choice, and it seems to me to be a step in the right direction (based on the TOC).

I would also like to second your point that CS is more than algorithms and data structures. I feel Dijkstra would not approve of thinking about CS as "that thing you do after learning a programming language".

<comment><USER9> I found "Introduction to Algorithms" to be _waaay_ too dry to deal with in beginning, though I'd welcome something else to get through the detail.

Personally I'd use Cormen as "dictionary" to get into detail of stuff I first read in A.D.M.

</comment></comment></comment><comment><USER13> I wrote two of them specifically for self taught programmers like her: "Classic Computer Science Problems in Python" and "Classic Computer Science Problems in Swift." Unfortunately we don't have a JavaScript version yet. Instead of focusing on things like complexity analysis we focus on problem solving techniques in a tutorial like fashion. You can find out more at: [https://classicproblems.com](https://classicproblems.com)

<comment><USER14> Not OP but will check those out, thanks!

</comment></comment><comment><USER15> There's so much more to CS theory than big O notation and you're in for a treat if you check out any of the below - happy to share more if people are interested.

1\. [https://www.amazon.com/Computational-Complexity-Approach- San...](https://www.amazon.com/Computational-Complexity-Approach-Sanjeev- Arora/dp/0521424267/ref=sr_1_3?keywords=complexity+theory&qid=1566146955&s=gateway&sr=8-3)

2\. [https://www.amazon.com/Quantum-Computing-since-Democritus- Aa...](https://www.amazon.com/Quantum-Computing-since-Democritus- Aaronson/dp/0521199565/ref=sr_1_1?crid=H43HH53HNDKQ&keywords=quantum+computing+since+democritus&qid=1566146985&s=gateway&sprefix=quantum+computing+since+dem%2Caps%2C191&sr=8-1)

3\. [https://www.amazon.com/G%C3%B6del-Escher-Bach-Eternal- Golden...](https://www.amazon.com/G%C3%B6del-Escher-Bach-Eternal- Golden/dp/0465026567/ref=sr_1_1?keywords=godel+escher+bach&qid=1566147014&s=gateway&sr=8-1)

4\. [https://www.amazon.com/Introduction-Theory-Computation- Micha...](https://www.amazon.com/Introduction-Theory-Computation-Michael- Sipser/dp/113318779X/ref=sr_1_1?keywords=sipser&qid=1566147058&s=gateway&sr=8-1)

</comment><comment><USER16> Before deep diving into CS theory, I would go deeper into programming first to better understand how a computer really works. The best intro on this topic I found is "Programming from the Ground Up" by Jonathan Bartlett [1].

"Programming from the Ground Up" starts at the bottom with CPU architecture and goes up from there to how functions work, dealing with files, code libraries, high-level languages, etc. Having a solid understanding here will provide immediate benefits in coding and serve as a strong foundation for some of the other recommended texts.

If you're interested, I recommend buying directly from Bartlett Publishing [1]. Bartlett published the book under the GNU Free Documentation License and there are multiple copy-cat versions on Amazon.

[1] [http://www.bartlettpublishing.com/site/catalog/programming-f...](http://www.bartlettpublishing.com/site/catalog/programming- from-the-ground-up/)

<comment><USER17> Would like to add Nand2Tetris[1] which falls in a similar category.

[1]: [https://www.nand2tetris.org/](https://www.nand2tetris.org/)

<comment><AUTHOR> I actually recommended this to her already - the book (The Elements of Computing Systems) of the same course was the first programming text I ever read. Really enthralling!

</comment></comment></comment><comment><USER18> Structure and interpretation of computer programs (free online) [https://en.wikipedia.org/wiki/Structure_and_Interpretation_o...](https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs)

</comment><comment><USER19> Aho/Ullman Foundations of CS [http://infolab.stanford.edu/~ullman/focs.html](http://infolab.stanford.edu/~ullman/focs.html)

O'Halloran/Bryant CSPP [https://csapp.cs.cmu.edu/](https://csapp.cs.cmu.edu/)

David Money Harris Digital Design... [https://booksite.elsevier.com/9780128000564/](https://booksite.elsevier.com/9780128000564/)

<comment><USER20> Comprehensive and Worthy suggestions.

The first one was new to me. Looks quite good.

<comment> denton-scratch The classic "Foundations of CS" was referred to in my youth as simply "Aho and Ullmann". As I recall, it contained a particularly comprehensive explanation of the construction of parsers, compilers, interpreters and translators.

<comment><USER20> You are thinking of a different book by "Aho and Ullman". The text listed above deals more with "Discrete Maths" and "Computer Science".

</comment></comment></comment></comment><comment> denton-scratch Most of these answers seem to be books about algorithms.

Computer science is much broader than that; it includes databases, AI ( _not_ the same as algorithms!), computer architecture, topics such as hardware interfacing, history of computing, and some overlap with areas in philosophy.

I didn't ever formally study CS, but I did read several books on algorithms. Especially notable is the seven-volume work "The Art of Computer Programming" by Donald Knuth; in particular the volumes "Fundamental Algorithms", "Sorting and Searching", and "Seminumerical Algorithms" are timeless masterpieces, entertaining and witty, and they totally nail their subject-matter. If you think CS is equivalent to "algorithms", then read these books.

N.B. I understand that some of these books have been re-written to use a revised version of Knuth's MIX machine language, to allow the examples to embody modern developments such as pipelines, caches, and parallelism. I haven't read these updated editions; no doubt they are even better than the originals.

But I think CS is a much broader field than algorithms.

[edit] Harrumph. Wikipedia says that only three-and-a-bit volumes have yet been published. Seven volumes was the original plan. Smacks a little of George R. R. Martin?

<comment><USER21> > Harrumph. Wikipedia says that only three-and-a-bit volumes have yet been > published. Seven volumes was the original plan. Smacks a little of George R. > R. Martin?

My favourite poke at this is Charlie Stross' book the Atrocity Archives (a kind of Lovecraftian, CS nerd horror / humour novel where advanced mathematics is dangerous), wherein Knuth did in fact finish the 4th edition, but it contained secrets that immediately got it shut down by various governments.

</comment></comment><comment><USER22> See what some (reputable) universities in your country use for their data structures and algorithms class, and then use that.

Avoid books with a programming language in the title, because those will try to teach both basic programming and the interesting material.

</comment><comment><USER23> I strongly advise the following:

\- The Computational Beauty Of Nature, by William Gary Flake

\- The Impostor's Handbook, by Rob Conery

\- The Elements Of Computing Systems, by Noam Nisan & Shimon Schocken

</comment><comment><USER24> I'm a fan of Algorithm Design Manual. It's also what Google and FB recommend for interview prep.

[https://smile.amazon.com/Algorithm-Design-Manual-Steven- Skie...](https://smile.amazon.com/Algorithm-Design-Manual-Steven- Skiena/dp/1849967202)

</comment><comment><USER25> For a gentle introduction to algorithms and Big O, "Grokking Algorithms" is easy to read and fun. For more in depth and systematic study, Sedgwick's "Algorithms" is a very clear and beautiful book.

For computer architecture, Petzold's "Code" is wonderful.

</comment><comment><USER26> Mike Sipser's book: [https://www.amazon.com/dp/113318779X](https://www.amazon.com/dp/113318779X)

<comment><USER27> This is a great book. I recommend learning this book with professor Porter's course on theory of computation. [https://www.youtube.com/watch?v=TOsMcgIK95k&list=PLbtzT1TYeo...](https://www.youtube.com/watch?v=TOsMcgIK95k&list=PLbtzT1TYeoMjNOGEiaRmm_vMIwUAidnQz)

</comment></comment><comment><USER28> The New Turing Omnibus: Sixty-Six Excursions in Computer Science [https://www.amazon.com/dp/0805071660](https://www.amazon.com/dp/0805071660)

</comment><comment><USER29> Probably a little more advanced than what you are looking for but I would like to recommend The Nature of Computation by Cristopher Moore and Stephan Mertens as a next step. It is such a fun book to read, with a lot of problems and exercises.

[http://nature-of-computation.org/](http://nature-of-computation.org/)

</comment><comment><USER30> You mentioned getting to grips with complexity analysis. Has she looked at the book Think Complexity[1]? It seems pretty cool and related to that area of study.

[1]: [http://greenteapress.com/complexity/](http://greenteapress.com/complexity/)

</comment><comment><USER31> Mentioned before, but I'll +1 these: \- The Impostor's Handbook: Rob Conery \- Foundations of CS: [http://blough.ece.gatech.edu/3020/focs.pdf](http://blough.ece.gatech.edu/3020/focs.pdf)

Also be sure to check out

\- Software Fundamentals, essays by David Parnas

Here's one of the essays from the book: [https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria...](https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf)

Parnas promoted the idea of encapsulation before the word had even been invented. And at the time, the idea was actually controversial, if you can believe it.

</comment><comment><USER32> I'm a CS grad student at Caltech. My absolute favorite intro theory book (the one I recommend to undergrads and people just starting out) is Algorithms by Vazirani, Dasgupta, and Papadimitriou. Extremely well written and a great selection of topics.

</comment><comment><USER33> I would recommend the Dasgupta and Vazirani book on algorithms. It has a balance between theory and practice. Plus it has a lots and lots of exercises which I found very helpful for practising.

</comment><comment><USER12> I already addressed your question in another comment, but I would like to write a second point: a book seems to me the wrong way to go.

Unless your friend is a natural born comp. scientist, she'll need someone to point out what's important, what's not, which exercises she _must_ solve before moving on and which topics she can take in parallel if she needs a break.

Of course, a course takes time. But if someone doesn't find the time to take an online course, where will they find the time to (properly) read the book?

<comment><USER34> I suppose a book could be written more as a course than a comprehensive reference manual?

</comment></comment><comment><USER35> A really good overview of the field of CS is _Great Principles of Computing_ by Peter Denning and Craig Martell, 2015. It's a good book for CS students who want overviews of less familiar areas of computer science, and for anyone (in other areas) who want to know more about computation.

Another is Subrata Dasgupta's _Computer Science: A Very Short Introduction_, a 2016 addition to Oxford's Very Short Introduction series. It has over five pages of further references to more detailed and specialized works.

</comment><comment><USER36> Penn has a master's program, the MCIT ([https://onlinelearning.seas.upenn.edu/mcit/](https://onlinelearning.seas.upenn.edu/mcit/)), that's designed to be a highly condensed undergraduate program in computer science. The materials from the core courses there are a very good place to start looking. My guess is that the bootcamp covered mostly stuff from 591 and 594, so the other four courses will be new.

</comment><comment><USER37> You should start reading The Art of Computer Programming by Donald Knuth, and solve all exercises (including ones having difficulty level 50). If you catch up finishing all currently existing volumes before Knuth finishes, with all the exercises answered thoroughly; you can consider yourself a self-taught algorithms expert.

</comment><comment><USER38> PAPL [https://papl.cs.brown.edu/2018/index.html](https://papl.cs.brown.edu/2018/index.html) There's lectures for it too: [https://brown.hosted.panopto.com/Panopto/Pages/Sessions/List...](https://brown.hosted.panopto.com/Panopto/Pages/Sessions/List.aspx#folderID=%222559ad35-3fff-4ef1-a2ac-a951011eb91e%22&maxResults=50)

Tell your friend to download the lectures locally before they disappear. It will cover estimating complexity, solving recurrences, memoization, dynamic programming, etc. All the assignments can be done in a browser as they're in Pyret.

Ripping the vids cannot be emphasized enough, these lectures always disappear after a few months.

</comment><comment><USER39> For understanding complexity watch this video [https://www.infoq.com/presentations/Simple-Made- Easy/](https://www.infoq.com/presentations/Simple-Made-Easy/)

Another way to thing theory of programming logic is a general understanding of language logic for which I recommend [https://www.amazon.com/Philosophy- Language-P-Martinich/dp/01...](https://www.amazon.com/Philosophy-Language-P- Martinich/dp/0199795150/ref=mp_s_a_1_1?keywords=david+sosa&qid=1566131878&s=gateway&sr=8-1)

I am going through that book myself right now. It came to me highly recommended. I don't have a computer science degree.

</comment><comment><USER40> Bentley, "Programming Pearls"

[https://www.goodreads.com/book/show/52084.Programming_Pearls](https://www.goodreads.com/book/show/52084.Programming_Pearls)

</comment><comment><USER41> "complexity analysis" ... "stuff you would learn in a computer science degree".

Does she want theory? Does she want Software Engineering skills? Does she want to be able to get a job?

Cracking the Code Interview might be a fine jumping off point. It covers a lot of topics at a very readable level. If she doesn't understand it from the books angle, then she can do research on her own until she gets there. It covers stuff like "complexity analysis" in-depth enough for most people.

</comment><comment><USER42> I would highly recommend Imposter's Handbook[1] by Rob Conery

Then there is also excellent BaseCS Podcast [2]

[1] [https://bigmachine.io/products/the-imposters- handbook](https://bigmachine.io/products/the-imposters-handbook) [2] [https://www.codenewbie.org/basecs](https://www.codenewbie.org/basecs)

<comment><USER43> I would find it very difficult to recommend this book - I think parts of it are simply factually mistaken, unfortunately, and I worry someone using knowledge from it would make themselves look like _more_ of an imposter, not less.

[https://github.com/imposters- handbook/feedback/issues/50](https://github.com/imposters- handbook/feedback/issues/50)

The book itself is a good idea and the author seems to have good intentions even if they didn't take advice in this case, though.

</comment></comment><comment><USER44> 'The CS Detective' is the most well written introduction to Computer Science theories I have ever come across: [https://nostarch.com/csdetective](https://nostarch.com/csdetective)

It is approachable, fun, and engaging. It frames concepts inside a 'detective' story, making the explanations less abstract and more practical.

</comment><comment><USER45> Structure and Implementation of Computer Programs. A master piece, a bit challenging but immensely fun for a certain kind of people.

<comment><USER46> Typo for "Structure and Interpretation of Computer Programs"?

<comment><USER45> Yes, thank you.

</comment></comment></comment><comment><USER47> _Algorithmics_ by David Harel. Not a textbook, but a more popular _Scientific American_ level treatment. Very readable and accessible but quite rigorous also - Harel's a noted computer scientist. I recall there was a slightly different edition of this book called something like _Algorithms - the Soul of Computing_.

<comment><USER20> Seconded. This is a good recommendation particularly for somebody who is just starting out (the OP has only done a js bootcamp and so has a _very_ long way to go!)

Pair the above with Petzold's "Code" and you get a very good idea of both the Theory and the Machine.

</comment></comment><comment><USER48> I second the suggestion "Foundation of Computer Science" the full book is available as pdf. its language is clear. it uses C langauge. there is another edition using Pascal (which I have and IMHO is better even when learning about data structures involving memory references). you may also find a dirt cheap used copy.

</comment><comment><USER49> Are there any recommendations for books thats are less algorithms and more how to structure software, how to structure databases and data and how to build reliable apps/websites and reduce spaghetti code?

<comment><USER20> At the Architecture level see the very good book "Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems" by Martin Kleppmann.

For actual code, you do not have one book but have to glean the knowledge from a whole bunch of them.

</comment></comment><comment><USER50> There is a book called Grokking Algorithms (forgot the author), it's a more gentle intro to algorithnd, I would strongly advise that book for someone that completed a bootcamp.

</comment><comment><USER51> It's not just algorithms. Creating maintainable code and building good habits matter too.

For that, I'd recommend The Pragmatic Programmer, A.Hunt, D.Thomas.

</comment><comment><USER52> Maybe it would be possible to give a somewhat useful first answer just as a post here; I'll try.

Going way back in computing, often an important issue was, how fast will a program run? That study is now sometimes called _computational time complexity_.

This study was important because, for some common work, some ways of programming the work ran many times faster than some other ways -- i.e., the study of computational time complexity got some big results.

Usually in practice an issue of a little less concern than running time was how much of the computer main memory would a program need, and this study was _computational space complexity_.

The first big case of big gains was running time for sorting. So, for some positive integer n, we are given n numbers (or alphabetic names, etc.) and want to sort them into ascending order. So, an obvious first approach is to look at all n numbers one at a time and find the smallest. Then look at the remaining n - 1 numbers and again find the smallest. Then with a little algebra, the running time grows proportional to n^2 (n times n, n _squared_ ). So we say (I'm omitting some fine points) that the running time is "big O n^2" written

O(n^2).

Now for some big stuff: (1) There is a way (method, technique, _algorithm_ ) called _heap sort_ with running time (computational time complexity)

O(n log(n) )

both on average for _random_ numbers and also for the worst case of the order of the given n numbers. (2) Heap sort works by comparing numbers two at a time (so did our

O(n^2)

algorithm above), and there is a cute counting result from A. Gleason, long a math prof at Harvard, that shows that for sorting by comparing numbers two at a time

O(n log(n) )

is the fastest possible. (3) Heap sort is also _in-place_ which means that the storage used, except for a constant independent of n, is just what is needed for the n numbers being sorted.

After sorting, there was interest in working with _trees_. Likely the tree most people are most familiar with is the hierarchical file system. A tree can be good for keeping a set of numbers in order while adding numbers to the set or removing numbers from the set. To get good guaranteed fast running time, we want the tree _balanced_ , that is, all the paths in the tree from the root to the leaves are about the same length. So, keeping the tree balanced while making the changes and doing so with relatively fast worst case running time was a challenge. One solution was AVL trees (see D. Knuth's _The Art of Computer Programming: Sorting and Searching_ or more recent books listed in this thread) and, mostly for data stored on disk, B-trees. Actually there are several important, that is, relatively fast, algorithms for manipulating trees.

Early on in computing there were more problems with algorithms that improved running time, e.g., string searching.

There is a general technique, _dynamic programming_ , that is the basis of several important, relatively fast algorithms. Here the _programming_ is in the sense of the English project _planning_ , that is, from the field of _optimization_ in _operations research_.

Generally, given a program, it can be difficult to do algebraic manipulations, say, assuming either random or worst case inputs, to find the "Big O" running time. Knuth's book starts with a lot of algebraic techniques that can help finding Big O running times. That work can be as challenging as we please.

There is some work that early on was not really in computer science but very much needs computers and where running time was and is a huge issue. An important source of such work was optimization in operations research. The first work of concern was the simplex algorithm of linear programming. Next was the closely related integer linear programming, i.e., combinatorial optimization. There were too many cases of problems starting with n numbers and running in

O(2^n)

which is _exponential_ and so bad that, for too many realistic problems, we could run for billions of years with about the fastest computers we can imagine and big enough to fill the visible universe, literally.

So, a question became, can we have some positive integer k and have worst case running time grow only as

O(n^k)

that is, a polynomial in k? The problem was generalized and now is the question of P versus NP, the leading question in computational complexity and maybe in much of computer science and pure and applied mathematics. The standard example of such a problem is the traveling salesman problem were we are given some n cities and ask for the shortest path that visits each city exactly once.

That's a nutshell start on _computational time complexity_ in computer science.

<comment><USER52> Errata: Should revise

"there is a cute counting result from A. Gleason, long a math prof at Harvard, that shows that for sorting by comparing numbers two at a time

O(n log(n) )

is the fastest possible."

by adding at the end "for worst case performance".

Should revise

"Then look at the remaining n - 1 numbers and again find the smallest."

by adding at the end "etc.".

Generally computer science computational complexity ignores long lists of ways to write code that runs faster, e.g., for a result needed more than once, compute it just once and store the result and don't repeat the calculation.

Instead, the emphasis is on some _larger_ aspects, e.g., just counting comparisons. Broadly that emphasis is usually appropriate since as n grows quite soon some crude code of a O( n log(n) ) algorithm will run many times faster than careful code of an O( n^2 ) algorithm.

<comment><USER52> Errata: adding at the end "for average case performance".

</comment></comment></comment><comment> denton-scratch "Most of the code you write is run by an operating system, so you should know how those interact."

 _All_ of the code you write is run by one or more CPUs; operating systems provide supporting software, they don't "run" programs (although they may schedule them for execution, which isn't the same).

</pedant-mode>

<comment><USER53> It's not that clear cut. Virtual Memory for example is not just hardware.</comment></comment>


SaaS marketing tactics and case studies - <AUTHOR> https://apollodigital.io/blog/saas-marketing <comment><USER2> If you're a founder scanning this list and feeling overwhelmed: Don't worry, this is not a list of strategies. It's a list of tactics that your marketing team may or may not deploy as part of an actual strategy.

(If you tell a Sand Hill Road audience that your go-to-market strategy is, say, "Strategy #31 -- Launch Your SaaS on ProductHunt," or give a list that's 43 items long, you'll get laughed out of the room before you can pop open the lightly flavored seltzer they gave you.)

You can safely ignore this list until you figure out a real strategy, and once you do just hand this list over to your marketing manager in case they run out of ideas.

<comment><USER3> Agreed - I've had a lot of conversations around marketing for SAAS companies and tried to put them into more of a visualization:

[https://docs.google.com/spreadsheets/d/1l-0VLKWIzqu2dwyxmmNJ...](https://docs.google.com/spreadsheets/d/1l-0VLKWIzqu2dwyxmmNJB3PaeygHagTGzg1QBsoHyWU/edit?usp=sharing)

Should be noted that this is really from the perspective of B2B SAAS.

</comment></comment><comment><USER4> I'd suggest adding time to this. For example, Content Marketing is great but won't do anything significant for at least a year but PPC is instant.

Sometime you need it fast :-)

</comment><comment><USER5> These are all tactics / campaigns, not strategies. A LinkedIn ad is not a strategy.

<comment><USER6> I am genuinely curious about this. If Linkedin Ad is tactic, what would be the corresponding strategy ? I am asking because currently, my B2B SAAS business is totally lost on digital Marketing and we are trying to figure out how to solve the problems.

<comment><USER5> The corresponding strategy would be to have an overarching campaign narrative which was aimed at achieving a specific goal (registering interest, requesting a demo, signing up for a trial account, visiting a campaign page and going further down the funnel), or establishing a specific position for your brand in the market. This would be mapped to specific KPIs or metrics that you wanted to achieve.

A LinkedIn ad (or a Facebook ad, microsite, TikTok, Snapchat), targeted at a specific audience or audience subset, might be one tactic amongst many that you used to drive people toward achieving this goal. You would have different tactics for different parts of the funnel (i.e. an ebook for someone at the top, and a demo or webinar for someone at the bottom). You would then measure the success of these tactics to determine where to direct spend to achieve your goal.

<comment><USER6> Thanks. That clears it a bit more. Do you do consulting on the side ? Would love to talk more about this.

<comment><USER7> Not parent, but I could help you out. carl@ my username .com

</comment></comment></comment></comment></comment><comment><USER8> > "Install an email-tracking tool."

No, please don't do that.

</comment><comment><USER9> Great list, would love to see a budget range for each of the tactics, the definition of small/medium-high budget can vary greatly depending on who you ask!

<comment><AUTHOR> We actually wanted to do a budget range, but it gets real complicated real fast. A micro-site, for example, can cost you anything from (technically) zero because you have an internal team, to 6-figs because you're using an overpriced dev agency. The same applies to most things. You can build links for nearly free with an outsourced link-building team, or you can hire freelancers that charge 1k / outreach

<comment><USER10> Nothing costs you zero. Everyone on your team (I assume) is paid but even if they are not compensated with cash or stock, their time is not free

<comment><AUTHOR> My point exactly, that makes it even more complicated.

<comment><AUTHOR> You're really getting into semantics here. Yes, an internal team does NOT mean zero costs. I was just trying to make a point.

Want to discuss content? Make a comment about content, not the way something is worded

<comment><USER10> I asked you about content strategy vs tactics in another comment and you responded with "tomato tomat-o". Not the most engaging of replies. It's apparent this was click bait to begin with.

<comment><USER11> I don't think it's click bait. There is a lot of practical advice in the article and real examples of implementation. His "tomato" answer is a refusal to engage and be helpful, but the article itself is a very good roundup of marketing tactics. I am not affiliated with Apollo, but I do help startups with lead generation and can recognize quality content in an area I have expertise in.

<comment><USER10> I agree there is some useful content in the article however there is nothing original. The article is a compilation of marketing tactics that can be found when you search for "marketing tactics". It just feels like a lazy and thrown together attempt to push site traffic for them. Maybe I am being overly critical, if the HN community as a whole likes the post and content then great!

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER12> Thanks for a great resource!</comment>


Ask HN: NCombinator, feedback? - <AUTHOR>

Here's our site: http://ncombinator.com
We're trying to build an "open source ycombinator" that is less about investment, and focuses on the one aspect every YC alumni says is the top advantage of YC: "the network".
Our first post got booted. Another HN reposted it and that got booted too.
So we'd like to ask, what do you hate? (besides the name... which we're changing). Obviously we're big fans of YC's ideas so our goal is purely to spread those ideas farther and wider.
Thanks! <comment> saiko-chriskun really they got booted? I signed up as soon as I landed on the site, sounds really cool. Why would people hate on this? :(

</comment><comment> jack-r-abbit What do you mean by "got booted"?

<comment><USER2> The site was hastily taken off the front page...twice. It seems the flagging mechanism has given some users way too much power, or the submission was artificially removed.

<comment> jack-r-abbit So... "flagged off the first page". That is what I thought they meant. But the idiom "getting the boot" generally means being removed or kicked out... which doesn't really apply here. Carry on.

</comment></comment></comment><comment><USER3> Will this get booted too?</comment>


Programmers should not call themselves engineers - <AUTHOR> https://www.theatlantic.com/technology/archive/2015/11/programmers-should-not-call-themselves-engineers/414271/?single_page=true <comment><AUTHOR> This needs discussion</comment>


Ask HN: What's next big thing after iStuff? - <AUTHOR>

As the name suggest... <comment><USER2> gStuff.

<comment><AUTHOR> What is that?</comment></comment>


Amazon's Silk Browser tracks users' visited URLs - <AUTHOR> http://techcrunch.com/2012/09/07/amazons-silk-browser-now-tracking-user-behavior-for-new-trending-now-section-wait-what/

<comment><USER2> EFF has previously examined silk and concluded, "We are generally satisfied with the privacy design of Silk, and happy that the end user has control over whether to use cloud acceleration..."

[https://www.eff.org/2011/october/amazon- fire%E2%80%99s-new-b...](https://www.eff.org/2011/october/amazon- fire%E2%80%99s-new-browser-puts-spotlight-privacy-trade-offs)

I don't think showing sites that are trending in aggregate changes anything. This seems like a nonstory.

<comment><USER3> Also, it's possible the concept of 'trending now' may not impact user privacy - the whole point of Silk is that pages are partly pre-rendered on Amazon's servers, so it could be implemented as simply as seeing which parts of the cache are being hit frequently.

I don't really know much about how Silk is actually implemented, but it seems like all we know so far is that they're doing at least as much tracking as your ISP already is (and frankly, I find that much more concerning).

<comment><USER4> Agreed, and if I recall correct, you can turn that feature off and call websites directly.

</comment></comment></comment><comment><USER5> Chrome's sync (i.e. sign in to Chrome) uploads the cleartext of your full browsing history to Google by default: [http://gregoryszorc.com/blog/2012/04/08/comparing-the- securi...](http://gregoryszorc.com/blog/2012/04/08/comparing-the-security-and- privacy-of-browser-syncing/)

From a privacy perspective Chrome and Silk sound the same.

Now, maybe Amazon is more actively using that data and doesn't provide means to change privacy settings (Chrome allows you to locally encrypt). I dunno.

<comment><USER6> At least you're not signed in by default like you are on the Kindle.

</comment></comment><comment><USER7> The real key to look at here is whether or not they are associating your visited URLs with your amazon account (or whatever account you need to be logged into. not a Kindle owner).

They mention they don't collect PII which doesn't mean it isn't being associated to PII though.

</comment><comment><USER8> As long as the data is anonymized and aggregated properly and links with less then thousands of hits are never shown then there shouldn't be any problem.

One other interesting thing they could do with the data is if they started Amazon Search (they're caching a lot of the web as is) they could use their tracking of Google results to goose Amazon Search the way Bing did with IE tracking data.

</comment><comment><USER9> Does Silk also kick in for SSL websites (the previous version did, iirc)?

I hope they had the decency to disable it for SSL connections.

<comment><USER10> I don't think you understand Silk entirely, it's a web browser - it doesn't 'kick in,' it's how you connect to any web site.

<comment><USER9> Just trying to be succinct: what I meant is the "render on the server" concept, which the thing that differentiates Silk from every other browser.

<comment><USER11> Does it really render on the server? Doesn't it just proxy over SPDY?

</comment></comment></comment></comment><comment><USER12> So I guess this will be brought up every time a new Kindle tablet is announced. I suppose it's useful for those who haven't heard this before.</comment>


Recharge Your Phone Over the Internet - <AUTHOR> http://www.hypepotamus.com/people/bitenergy/

<comment><USER2> There is basically no way this is not a free energy scam.

<comment><AUTHOR> hahah check it out, FroskKiller! it's actually pretty cool...

<comment><USER2> What's cool about a fake doctor claiming to have a disruptive energy idea with the usual complete lack of prototype or cogent explanation?</comment></comment></comment>


Stream VByte: breaking new speed records for integer compression - <AUTHOR> https://lemire.me/blog/2017/09/27/stream-vbyte-breaking-new-speed-records-for-integer-compression/ <comment><USER2> Just to give you an idea of how effective this strategy seems to be, this seems very similar to what the _COST in the land of databases_ submission the other day was talking about, where choosing interesting, fitting algorithms for the problem instead of large distributed but general systems often yields very good results (enough such that a single thread can often beat 100+ core distributed systems).

In one of the linked prior blog posts[2] of his he linked to in the beginning of that article, he said this:

 _Using the Hilbert curve layout leads to a very simple compressed representation: having sorted the u64 values it uses to represent edges, one can simply delta-encode them (writing the differences between adjacent values). Because the Hilbert curve teases out locality, the gaps are often quite small, and therefore compress nicely. When I combined a variable-length integer encoding with gzip, the resulting file was only 45GB; about 2.8 bits per edge). Decompressed (with just the variable-length delta encoding), it is 154GB, which is the representation I used to get the measurements above._

He then goes on in his posts to comically trounce some large distributed systems.

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

2: [https://github.com/frankmcsherry/blog/blob/master/posts/2015...](https://github.com/frankmcsherry/blog/blob/master/posts/2015-02-04.md)

<comment><USER3> !#$!@# I was going to go try that out. ;) When doing the Chaos/Order stuff, the decompression was about half the CPU cycles, so thinning that could help.

Fwiw, the encoding I used wasn't VByte; because I was doing strict increments, I knew `0` wasn't a valid value to see, and used it to encode variable byte lengths (number of zeros: number of valid data bytes). Not smart, but easy to hack up, and gave me back 128-255 in one byte. I'm curious to check this out, now!

</comment></comment><comment><USER4> This method of compressing integer arrays in differences and then reducing the number of bits for each difference, is very efficient for many applications. We used it many years ago at a startup to compress and realtime render vector maps for mobile devices.

Not only made it the data really small (we could fit all the roads of a country like Germany in 5 MB), it was also blazing fast to decode. Our vector map renderer used to do the vector map decompression on the fly, while doing coordinate transformation, and rendering to the screen. That was really the trick to get realtime zooming and panning vector maps on ~100 MHz ARM CPUs with tiny data caches of the time.

We even took that compression scheme a step further from byte-bound to bit- granularity. Above article made me wonder, how our old scheme performs on today's CPU...

<comment><USER5> One of the problems with SIMD is that we can't do this kind of shuffle at bit granularity, at least not in one instruction.

<comment><USER6> if you want bit level granularity you can use either SIMD-BP128 or SIMD- FastPFOR from [https://arxiv.org/pdf/1209.2137.pdf](https://arxiv.org/pdf/1209.2137.pdf)

</comment></comment></comment><comment><USER5> This is indeed fast and simple, since the pshufb instruction allows unpacking of bytes into multiple zero-padded words in one step. This technique uses a precomputed table of shuffle patterns, so it's a short sequence of instructions to fetch control information for each 4-word sequence and apply the shuffle given.

</comment><comment><USER7> "I should mention that unlike Amazon, we did not patent our approach. We want you to use this in your commercial and open-source projects!"

Thanks Dan!

</comment><comment><USER8> Could there be a similar scheme for floats?

Also, is there a penalty for using float16s for CPU centric code?

<comment><USER9> Using fixed-point representation would allow using this compression method.

</comment></comment><comment><USER10> The example code should replace "datasource" with "databytes".

<comment><USER11> Na</comment></comment>


Use links not keys to represent relationships in APIs - <AUTHOR> https://cloudblog.withgoogle.com/products/application-development/api-design-why-you-should-use-links-not-keys-to-represent-relationships-in-apis/ <comment><USER2> Here is the problem with links in a nutshell:

> The server is now free to change the format of new URLs at any time without > affecting clients (of course, the server must continue to honor all > previously-issued URLs).

If you have to honor all previously-issued URLs then you aren't _changing_ your format -- you are supporting two formats from now on, the old one and the new one.

You can of course tell your users that you will deprecate the old format, but unless you are as powerful as Google your users may prevent you from enforcing a deadline for deprecation.

If the URLs in your API responses are FQDNs rather than relative paths, all of this gets significantly harder to deal with.

Even if you figured all of that out, links are not idiomatic if your users consume your api via an RPC or GraphQL.

<comment><USER3> >(of course, the server must continue to honor all previously-issued URLs).

Why is this true for non-user facing urls? Seems like an argument could be made that you only need to support the urls for as long as the response was cacheable.

<comment><USER4> It's an API. The client isn't likely to be a browser. If it's integrating with another system, those links may have quite a long life.

<comment><USER5> Caching behavior is not only about browsers.

<comment><USER4> For sure, but for most people using APIs to integrate with systems, caching is an unwanted middle way between always fresh and stored persistent, where local storage is the "cache", except it isn't invalidated using HTTP logic.

<comment><USER3> >except it isn't invalidated using HTTP logic.

You should be doing this. It helps a lot, actually.

</comment></comment></comment></comment></comment></comment><comment><USER6> I never had any uncertainty regarding where I can use a given entity id in a well designed API. Fix the naming and organization of your API if that's a problem for your users.

Conversely, I often need to log or store API-provided entity ids on my side, and having to parse it out of a URL or store irrelevant URL bytes in my own database would be really annoying.

You're not going to avoid the need to compile entity URLs on the client side either, unless you only make requests to entities returned by the API, which would be a weird constraint to design client code around.

I really don't see the point to any of this.

<comment><USER7> I would never feel comfortable `fetch`-ing the URI provided by the API without validation. That sounds like a security issue waiting to happen.

<comment><USER8> Does an API returning only relative URLs address your concern?

The validation would be intrinsic in the client side concatenation of the server address with the relative URI.

<comment><USER6> (Not the GP) Yes, when done right, but it's iffy.

For example, the article includes URLs like "/people/123". The security of having a leading slash in these depends on API base URL.

"[https://api.hotstartup.com/v1"](https://api.hotstartup.com/v1") – safe

"[https://api.hotstartup.com"](https://api.hotstartup.com") – unsafe with ".evil.com/people/123"

I wouldn't really call this particular scenario a security issue, but allowing such things is a bad habit that _will_ eventually bite. It's like not HTML- encoding values like usernames that you "know" are safe (but you know are not HTML-encoded).

<comment><USER9> Yes, this is why developers should use URI-building libraries instead of direct string manipulation to modify URIs.

If I visit an HTML page with a link to ".evil.com/people/123" and click on it, the user agent won't append ".evil.com" to the hostname. You'd instead get something like "[https://api.hotstartup.com/.evil.com/people/123"](https://api.hotstartup.com/.evil.com/people/123") which would be safe (if not broken).

</comment></comment></comment></comment></comment><comment><USER10> I think this takes an overly-simplitisic view of APIs. Going by the primary example in the article, by representing a pet's owner as a link instead of an id, they're basically discounting the idea that there may be separate endpoints that take in an owner id. For example, if there was an endpoint that let you get the invoices by customer, you would still need to understand the templates for that endpoint.

More fundamentally, I think it's trying to solve a smaller problem in the face of a much bigger one, you still need to know what the response of any given endpoint is going to be. Just because they've passed me a link, doesn't me I don't need documentation on what endpoint that link points to. I still need to know that the owner is a link to the people endpoint so I can properly parse that result. That in turn requires just as much documentation (IMO) to describe the relationships as it would to properly document your URI templates.

Obviously, the primary reason to use links over ids is to give the developers of the API more control over changing things like routes and Ids and whatnot, but I feel like it is a bit disingenuous to make it out to be a much better user experience or something, since it really isn't.

<comment> rich-tea There shouldn't be separate endpoints that take an owner's ID. That's bad design. The owner endpoint should contain a list of invoices, ie. links to the invoice endpoint.

<comment><USER11> Do I misunderstand you or do you suggest that the customer object should include the list of all invoices? That does not scale. Imagine if it is something more common like transactions where a user can have made thousands or tens of thousands.

<comment><USER5> An API should usually prioritize ease of development over faithfully exposing database or architecture internals.

However, you can have it both ways: in the customer response, use

        "invoices": "/customer/7sn2J/invoices"

and have the server 307 redirect to "/invoices?customer=7sn2J", or whatever you prefer.

</comment></comment></comment></comment><comment><USER12> There's literally not a single upside of this shown in the article.

> The server is now free to change the format of new URLs at any time without > affecting clients (of course, the server must continue to honour all > previously-issued URLs).

No more than it was previously.

> The URL passed out to the client by the server will have to include the > primary key of the entity in a database plus some routing information, but > because the client just echoes the URL back to the server and the client is > never required to parse the URL, clients do not have to know the format of > the URL.

Instead, you now have to require new kind of knowledge, one of the keys which must be present in schema and their meaning. E.g. knowing that "pets" key is present and leads to a relationship of a particular kind, with all the implicit logic added and documented. And what if you want to get pet's owners with some additional parameter, like only getting ones which are exclusively yours? Would you need to edit that "pets" url adding "&exclusively_owned=true"?

<comment><USER13> I can think of one upside: it does make your keys more distinct. I can tell at a glance that /pets/12345 is a different category of entity from /people/98765\. That could aid in debugging. It's a bit like a type system.

And of course since it is a type system, it now means you've got yet another type system to deal with in your universe. One with unknown and inconsistent semantics, and no natural support built in. Conceivably those semantics could be added and software built to support it, but rolling your own is going go yield a lot of effort with much less benefit.

<comment><USER12> Yeah, but it would essentially still be more of a "string id" rather than a URL, e.g. you can just make your ID to look like "person-12345" and "pet-52435" without tying it to URL. Showing as valid URL can be a "nice artefact" to remove the need to lookup API docs for collection names.

</comment></comment></comment><comment><USER14> I don't mind using a link, but I'd prefer to have both the exact id and the link to avoid having to parse a link in an unreliable way to get the actual id.

It's interesting how GraphQL changes the base point of the article concerning documentation/ease of api use.

In our GraphQL resolvers we typically add two fields, thing_id which resolves to the id string, and thing which resolves an object that you can drill into as desired.

I was starting to see a lot of GraphQL APIs only add "thing", which meant you had to do a lot of queries like below just to get the id.

      thing { id }

<comment><USER15> I suspect the link is the id, as in uniform resource identifier. So parsing would be a mistake. At least on the client side.

<comment><USER16> When you are orchestrating an interaction between several services where they are all using a shared identifier somewhere in their API, you need to extract that identifier if it's embedded in a URI.

So tonight we're going to regex like it's 1999.

<comment><USER17> The identifier is not embedded in a URI, the identifier _is_ a URI: instead of an integer id 1234 or a string id "1234", you can use a string id "[http://example.com/id/1234"](http://example.com/id/1234"). Typically, one service is responsible for creating the id but after that, it can be used to refer to the same entity in any number of services. EDIT: What makes it better than a free-format string id is that every person and tool knows how to de- reference it / look it up.

<comment><USER11> What determined which API owns a resource when the same resource is exposed in mutlipe apis (e.g you have a REST API and a AMQP feed)? In some cases it is obvious but in other cases it is far from clear.

I feel using urls as ids create more problems than it solves, especially if you use absolute urls. I have worked with cases where the same ID was used in 3 or 4 different APIs. None of them clearly the master.

<comment><USER17> The URI doesn't have to be fully owned by any single microservice. The JSON representation can more or less correspond to a HTML view and be served by the UI, or a separate API facade can combine the relevant pieces of information from various microservices.

</comment></comment></comment></comment></comment></comment><comment><USER18> Why did the author of this blog post decided to pass web links in resources and completely ignored standard practices such as RFC 8288 which employs the Link HTTP header?

[https://tools.ietf.org/html/rfc8288](https://tools.ietf.org/html/rfc8288)

Additionally, compact URIs (CURIES) are also widely used in this context.

[https://www.w3.org/TR/2010/NOTE- curie-20101216/](https://www.w3.org/TR/2010/NOTE-curie-20101216/)

I feel that the author tried to reinvent HATEOAS but skipped a cursory bibliographical review and jumped right into reinventing the wheel, and one which has already been reinvented multiple times (HAL, JSON-LD, etc...)

<comment><USER19> The post itself, and this response, illuminate a reality which we don't talk about -- the set of standards around HTTP are a horrible mess. As a person who in a past job has tried very hard to implement a "standards compliant" HATEOAS API, the sheer mass of complexity and vagueness is just too much. It's easier to just write something that works and which resembles something people are used to than to wade through these horrible RFCs trying to follow standards without good reason. It's like a horrible joke -- I wouldn't be surprised if you got to the final RFC and it said "Just kidding! Congratulations on getting this far, but this was just a test of your tolerance for pedantry."

This emperor has no clothes.

<comment><USER18> > the set of standards around HTTP are a horrible mess.

That's not the problem at all.

It would be the problem if the current state of the art was actually taken into account and discarded for some reason.

Instead, the state of the art (or even basic standard practices) is systematically ignored, and we end up seeing the same old wheel being supposedly invented again and again by people who fail to perform the flimsiest cursory bibliographical research on any given topic, and instead invest the bulk of their time announcing their poor reinvention of the wheel.

The web is based on linking. It's a very basic concept. Linking resources is not a new problem. What line of reasoning can possibly lead anyone to believe that this specific problem has never been researched by anyone before us, thus it's a sensible idea to simply dive head-first into coming up with a proposal that completely ignores any prior work?

<comment><USER19> Nope, the current state of affairs is an indictment of the "standards". It should be easy and obvious to implement something according to the standards, but it's not. I'm a relatively smart guy, and I've tried. You very quickly reach the point where you ask, "why the fuck am I doing this?" and just do what makes sense.

Let's take RFC8288 as an example since you've brought it up. Where in that RFC does it discuss _why the fuck_ I would want to put an API link in the headers instead of the body?

The fact is that this RFC isn't "the standard". The standard thing is to put API links in the body with other attributes, and it's the standard because that's what everyone does, and because that's what makes sense. This RFC is a hammer for HTTP pedants to hit people over the head with.

 _The web is based on linking_

And where to we expect those links to appear? In the header?

<comment><USER20> FWIW, RFC 8288 was preceded [1] by RFC 5988, and RFC 5988 [2] says in its section '1\. Introduction':

"A means of indicating the relationships between resources on the Web, as well as indicating the type of those relationships, has been available for some time in HTML [W3C.REC-html401-19991224], and more recently in Atom [RFC4287]. These mechanisms, although conceptually similar, are separately specified. However, links between resources need not be format specific; it can be useful to have typed links that are independent of their serialisation, especially when a resource has representations in multiple formats."

"To this end, this document defines a framework for typed links that isn't specific to a particular serialisation or application. It does so by redefining the link relation registry established by Atom to have a broader domain, and adding to it the relations that are defined by HTML."

[1] [https://tools.ietf.org/html/rfc8288](https://tools.ietf.org/html/rfc8288) [2] [https://tools.ietf.org/html/rfc5988](https://tools.ietf.org/html/rfc5988)

<comment><USER21> I might be missing the obvious, but I don't see in your quote the answer to the question:

> Where in that RFC does it discuss _why the fuck_ I would want to put an API > link in the headers instead of the body?

<comment><USER20> The answer is in the part that says "it can be useful to have typed links that are independent of their serialisation, especially when a resource has representations in multiple formats".

In HTTP, URLs locate a 'resource'. Then you and the server do content negotiation, implicit and/or explicit, to select a 'resource representation'. Think of these as different formats for the same conceptual thing identified by the URL. Some formats like HTML can support hypermedia that can have embedded links. Some, like 'text/plain' or 'image/gif', can't.

Link headers allow links from the current resource to other resources to be communicated even if the chosen representation can't communicate links in its body.

<comment><USER21> Got it, thanks. How do you define 'the chosen representation can't communicate links in its body'?

<comment><USER20> You as the client try to GET /my-receipts/20190512-1 from Fancy Receipt Scanning Service, and content-negotiate with an Accept header to "text/plain" or "image/gif" (e.g. to get a plain copy or a scan). There's no agreed-upon way of communicating links in plain text or GIF, so Fancy Receipt Scanning Service can't serve you a GIF scan of your receipt that links to a product page for every item you bought.

If you accepted "text/html", it could have served HTML that embedded these links within the response body, but you didn't accept "text/html".

It can choose to send links as headers, if it still wishes to communicate links.

<comment><USER21> That's fair, but if I'm defining an API that serves, say, JSON, I can define a schema for it and tell my clients what things mean in the schema, including which things are links.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER22> A thing may be identified by a URI (/person/123) for which there are zero or more URL routes (/person/123, /v1/person/123). Each additional route complicates caching; redirects are cheap for the server but slower for clients.

JSONLD does define a standard way to indicate that a value is a link: @id (which can be specified in a/an @context) [https://www.w3.org/TR/json- ld11/](https://www.w3.org/TR/json-ld11/)

One additional downside to storing URIs instead of bare references is that it's more complicated to validate a URI template than a simple regex like \d+ or [abcdef\=\d+]+

<comment><USER23> And on a more fundamental standpoint I get that disk space is cheap theses days. But you just doubled, if not worse, the storage space required for a key for a vague reason.

It may never make any difference on a small dataset, where storage was anyway unaware of differences between integer and text. But it would be hiding in the dark. And maybe in a few year a new recruit will have the outstanding idea to convert text-link to bigint to save some space...

</comment></comment><comment><USER24> The idea of using uris instead of keys is not a new one (as has been mentioned by other commenters). Every few years the idea gets a resurgence of people who say that REST apis should be HATEOS and that _we are doing it wrong_.

It seems obvious that the cost-value for this is simply not there, if it was good enough, you'd see developers requesting it and many more vendors implementing it. So far I haven't seen any recent changes that might skew the cost-value towards the uri's favor, only the opposite (cue GraphQl).

Using uris have little benefits, but it does have the following problems:

As a user of the api:

* You need to keep an arbitrary length key in your database if you save references. It can cause some issues with certain setups (less so these days though).

* If you keep the entire URI as identity, then you can't use multiple endpoints. For instance lots of companies have an endpoint for production and one for reports - using URI for one endpoint in another is quite awkward.

* Working with queries is troublesome, especially with get request. Consider searching for all transaction of a specific account, where the account's identifier is `[https://api.google.com/v1/account/123`](https://api.google.com/v1/account/123`)

* Upgrading to a new version of the api (one with a different url like v1/v2) now not only requires you to change your code to work with the new version, but also migrate all previous ids you kept in your database, which is a much different and more error-prone issue then simply changing code.

<comment><USER25> One simple strategy is not to change your approach to storage of IDs, which can continue to be "simple" keys. If you use that strategy, the only change from a "conventional" application is that the server is doing all the URL<->simpleId conversions instead of pushing that responsibility onto the client. Another good strategy is to store Ids in the form that the URI spec calls "path-absolute" URIs — basically you lop off the scheme and authority. This strategy works well, but may require a bit more care, and may cause problems if you have to integrate with other tables that have a different approach to keys.

</comment></comment><comment><USER26> The article knowledge has been lost to time. In "relational databases" you always name the foreign key as the relationship between tables.

From "A Practical Guide to Relational Database Design" from the year 2000. "Each relationship line should carry a pair of descriptive elements, which define the nature of the association between entities. A name is a single word or descriptive phrase; it should always contain a verb such as: owns, owned by, holds, administered by, etc. Examples from our simple model are: A PART is sold on an ORDER LINE. An ORDER LINE is placed for a PART."

But, this has been lost because the practicality is that it is hard to know what is the element. As other comments points.

Probably the best is both worlds: PersonId_Owner. PersonId_Veterinary. Or something similar.

It seems that such a discussion should have been solved decades ago. And here we are. :)

</comment><comment><USER27> I feel like the author has never used graphql. We're also just finally graduating past REST to something more meaningful. This advice feels 15 years late and now totally wrong. An API shouldn't be tied to a protocol like http, it should be able to move on to other things.

Ahh I was correct:

> I have never used GraphQL, so I can't endorse it, but you may want to > evaluate it as an alternative to designing and implementing your own API > query capability.

You really shouldn't write this giant article without having tried that.

</comment><comment><USER28> Hypermedia As The Engine Of Application State (HATEOAS)

[https://en.wikipedia.org/wiki/HATEOAS](https://en.wikipedia.org/wiki/HATEOAS)

The idea has been around for a while; I personally don't think it is a good idea.

There is even a content type (or two) for it: application/hal+json and application/hal+xml.

[http://stateless.co/hal_specification.html](http://stateless.co/hal_specification.html)

<comment><USER20> The article's recommendations don't achieve HATEOAS, because even though the foreign-key IDs are replaced with URLs, they're not actually links because they don't specify an explicit relationship.

Instead, the relationship between the response document and the URL's target is implicit, probably guessed from the naming of the key or maybe noted in the response document's definition.

The point of HATEOAS is that a client who understands the meaning of certain link relations (aka "rels"), such as ones in the IANA registry [1], can interact with these referred-to resources using the Standard Interface (of GET, POST, PUT, etc).

Only in the section where the article talks about ways to express links in JSON do link relations appear.

[1] [https://www.iana.org/assignments/link-relations/link- relatio...](https://www.iana.org/assignments/link-relations/link- relations.xhtml)

<comment><USER25> In the style of JSON I like to use, and whih GitHub and Google Drive use, the relationship name is given by the JSON name. So if you see 'owner: /person/12345', then 'owner' is the relationship name. There are other JSON styles for expressing the relationship name — the blog post mentions some of them. You might quibble about whether these names are the names of the relationship, or just names of one end of the relationship.

</comment></comment></comment><comment><USER29> I just don't understand why mixing two different concepts at two different abstraction levels only for some, apparent, simplicity.

On one level we got ID unique identifier of a resource, on another level we have URL, how to get a specific resources.

They are just different things that shouldn't be mixed.

What if tomorrow I want to get the same resource via graphql? Or in a message bus?

<comment> frosted-flakes Why can't the ID also be a link? Serious question. I don't see any real downside to it.

If the ID is also a link, it is guaranteed to be globally unique (like a Relay Node ID in GraphQL).

If you want to get the same resource via GraphQL, just use the same URL-ID. In fact, the author mentioned the possibility of base64-ing the link to prevent clients from relying on its structure, which is also a common pattern with IDs in GraphQL.

<comment><USER29> Is not that they can't, it is just that link are not designed to be ID.

The ID is the maximum cardinality of an entity (informally the smallest set of values of such entity necessary to uniquely identify it), the link is how to find the entity.

What happen if you want to deprecated your API?

There are other way to share the link of a resource,like use headers.

Then again, from a strictly practical point of view in 99.9% of the case it won't change anything, but:

1\. Eventually there will be cases where it does matter, and then it will be an huge mess.

2\. Why shut yourself a door only to don't read an header and obtain exactly the same information?

</comment></comment></comment><comment><USER30> What is the source of knowledge for the client about fields, where they can read link to the entity?

For human it's obvious that dog has an owner, so field "owner" should be used, but for code - you need to write it, "document it". So if you're going to "document" every field containing link to external resource, you'll end up with even more code, than just "documenting" API endpoints.

Also, pretty often you need multiple IDs of entities to send POST/PUT request - just to create a relation.

POST /adoption, owner_id=5, dog_id=7.

How should it look with links? Will it be issue for the server to parse them? And it's just simple case with 1 to 1 relation, sometimes you need to add sets of objects to another entity.

It's a really bad advice and after reading this I'm not sure I should trust other articles from that source.

<comment> frosted-flakes > Also, pretty often you need multiple IDs of entities to send POST/PUT > request - just to create a relation.

> How should it look with links?

Like this:

POST /adoption, owner=/people/5, dog=/pets/7

> Will it be issue for the server to parse them?

Why would it be?

<comment><USER30> Because it's more difficult than parse "5" and "7", especially when you need to parse not only numeral IDs. "More difficult" always means "more bugs" and "more vulnerabilities".

There is no single reason for this complication. The ONLY motivation author had - less knowledge about API endpoints on the client. But simultaneously it means more knowledge about the fields where links are stored, so it doesn't save nothing.

<comment><USER31> I believe "so it doesn't save nothing." should be written as "so it doesn't save anything." [0]

Feel free to ignore me.

[0] [https://www.quora.com/Is-the-sentence-dont-do-nothing- correc...](https://www.quora.com/Is-the-sentence-dont-do-nothing-correct)

<comment><USER30> thanks :)

</comment></comment></comment></comment></comment><comment><USER32> The document also forgets that API's are not read-only. So let's say you have users and usergroups and you can request a usergroup with its list of users and you can add users to usergroups.

If you use links for read, you should also use them for writes, otherwise it's quite inconsistent. So now you need to add a lot of parsing everywhere to extract the id's out of the urls, just for the sake of being more dogmatic

<comment><USER25> I have implemented many APIs in this style, both read and write. Depending on the design of the storage layer, the server may or may not have to parse ids out of URLs. The client never has to; for the client, the URL is the only Id.

</comment></comment><comment><USER33> I've literally spent 2 years working on a project that did exactly what this article is recommending. There were some places which needed the relative-url as an identifier, and other places which needed the "database id" as the identifier. We constantly had to extract the id from the URL, or convert the id into a URL, and keep a mental map of which format each input was using, and which format was needed for each output. It was a mess. I would personally not recommended this at all.

<comment><USER25> If some parts of your API used database keys as identifiers and other parts used URLs, then I can see that could be confusing. All one or all the other would probably be better.

<comment><USER33> Anytime you're interacting with the database, you'll need to use database keys. Anytime you're interacting at the API interface level, you'll need URLs. Anything in the middle is then going to be a gray area, especially when you have multiple people working on this implementation together.

</comment></comment></comment><comment><USER34> The caveats section of this article is longer than the content -- it makes a better case for _not_ using links as keys.

</comment><comment><USER35> Basically, advocating for dynamic typing rather than static typing, across an API boundary. You'll save code constructing API requests but need to create a lot of application logic to handle an owner link and pet link separately, since they have different semantics.

</comment><comment><USER36> No.

What's the point? None of this is useful to me, all of this is extra complexity. Why would I want to expose every addressable entity through URLs and HTTP? That's not what IDs are for.

I'm aware that this fits into the whole REST idea. I still don't care.

</comment><comment><USER37> I am surprised the article didn't mention RDF. In every data facet of RDF the data is uniquely identified by URI. In the case of RDF the URI is merely a unique identifier that can resolve to a HTTP resource, but doesn't have to.

</comment><comment><USER38> The fact that JSON is just a format standard and doesn't have specified components (like links etc) but instead we have to built those on top has cost us a lot in APIs. Btw, according to RFC 8288 Web Linking (and before that 5988), a link consists of 3 parts + 1 optional part:

"In this specification, a link is a typed connection between two resources and is comprised of:

       o  a link context,
       o  a link relation type (Section 2.1),
       o  a link target, and
       o  optionally, target attributes (Section 2.2).

       A link can be viewed as a statement of the form "link context has a
       link relation type resource at link target, which has target
       attributes".

       For example, "https://www.example.com/" has a "canonical" resource at
       "https://example.com", which has a "type" of "text/html".

"

That's why you need a standardized link component that is globally accepted/understood that takes into account all parts of the linking, instead of having various ways depending on the API/JSON-based Media Type to communicate that something is a link.

</comment><comment><USER39> I used links but I'm gonna rewrite this code to simply pass IDs. The reason is simple: I need additional configuration for my server to know its hostname and I don't want to do that. May be my server even have few different hostnames for different clients? So I must parse client request and extract Hostname? But it's served via reverse-proxy, so I must do some complex configurations to pass this information. So many issues. But client knows perfectly well which server he's talking to, so he can just append server-base and id. Yes, client must know about its structure, but it's nonsense that client can somehow learn something. I'll code that anyway.

May be it makes sense when you're writing an API and some different person writes a client and she's so shy that she don't want to even ask you. Yeah, she can inspect answer and find out that this seems like a link to query further. I never was in that situation, I was always building all software myself, so for me this does not make sense.

</comment><comment><USER40> I'm not sure about the verdict on URL versioning. I've used header versioning extensively and while flexible, it also carries some big downsides, mainly that it's confusing for new developers, and makes it real hard to casually explore the API in a browser (bad DX). I'm also not sure you do want to encourage mixing v1 and v2 API representations; I have certainly seen cases where it makes progressive upgrade easier, but it can also bring inconsistencies, so having a default new integrator path of "start at v2/login and use whatever links you get" is appealing.

I do like the idea from Stripe of having Accept header versioning, but pinning every new client to default to the newest GA version. Gets around most of the DX concerns I raised, but it's a bit more machinery to wire up.

</comment><comment><USER41> One advantage I see is that now you can do

      /pets?owner=/people/98765

      or

      /pets?owner=/org/98765

which makes your api more polymorphic.

Having said that I don't think URL is the right term to describe this. It's more like a <type, id> tuple.

</comment><comment><USER42> I wasn't fully convinced by this article. Language specific API wrapper clients can abstract all these complexities. Having links for IDs felt very unnatural but I guess that's because I have never came across an API that uses links like the article suggested

</comment><comment><USER43> Conceptual and data modeling aspects of this problem are discussed in [1]. It compares links with joins (and foreign keys) by proposing a solution (concept- oriented model) which does not use joins at all but rather relies on links only.

Essentially, a foreign key is viewed as a relational workaround for representing links with some significant drawbacks and the question is why not to use links directly without relational wrapping.

[1] Joins vs. Links or Relational Join Considered Harmful: [https://www.researchgate.net/publication/301764816_Joins_vs_...](https://www.researchgate.net/publication/301764816_Joins_vs_Links_or_Relational_Join_Considered_Harmful)

<comment><USER17> That seems like a highly relevant aspect to explore. For example, GraphQL does not specify joins and nesting is semantically a reference (directed link in the graph) instead. Any update on the cliffhanger?

 _> Yet, classical references miss some properties which are of crucial importance for data modeling. How links can be revisited in order to overcome these drawbacks will be our focus for future research._

</comment></comment><comment><USER44> Sometimes I wish REStful/REST the whole idea was a lot more opinionated. Sure you can have opinionated frameworks but nothing is stopping you from using a patch like I would a delete... (not the best example but you get the gist).

</comment><comment><USER45> I think the issue brought up in this blog post pales in comparison to the two biggest problems faced when working with REST APIs: querying for nested data, and the limitations of CRUD interfaces to model complex behavior.

<comment><USER46> I've been building REST apis for 13 years and never had either of these problems. I might be reading too much into this, but it sounds like you enjoy GraphQL or RPC-like apis and have trouble mapping their respective concepts 1:1 to REST. You shouldn't.

These architectures aren't equivalent alternatives. Pick the right tools for the job, and use the right tool appriately.

<comment><USER45> No I work mostly with REST apis and I find that api consumers don't really care about having nice relative links or references to self. If anything the popularity of GraphQL indicates that they want more flexibility than is usually available through REST and posts like this are the ones really addressing non-problems.

<comment><USER46> > If anything the popularity of GraphQL indicates that they want more > flexibility than is usually available through REST

I absolutely agree. GraphQL clearly addresses a pain point, or a gap. I just don't think it should be seen as a replacement. Pick the right tool for the job.

</comment></comment></comment></comment><comment><USER47> How do you write the article and never mention REST, hypermedia or HATEOS once?

<comment><USER25> It required some discipline. I had to catch myself several times. The reason I avoided those terms is that I wanted readers to focus on one simple idea and not get distracted by all the baggage those terms bring with them. You can see by the comments that I wasn't totally successful.

</comment></comment><comment><USER48> Why on earth would you blow out your request size for the sake of purity? Calling GET /pets is going to return a lot of instances of pet with very similar URLs.

</comment><comment><USER49> This is what Django REST framework had done right for years.

<comment> rich-tea Indeed. Hyperlinked serialisers are built in and super easy to use. And it makes so much sense when you use DRF's API browser too.

</comment></comment><comment><USER50> JSONAPI Specification also makes use of URLs in links to resources:

[https://jsonapi.org](https://jsonapi.org)

<comment> Seb-C I have implemented JsonApi a few times and so far it is the best one. It solves all problems I had about APIs in a very nice way. The `include` strategy is very simple and effective for dealing with relationships.

</comment></comment><comment><USER51> What really convinced me about HATEOAS and links was the first time I used a HAL browser and started clicking around to discover an API using only its entry point and navigating from there.

From that point on I try to use it as much as possible. A typical API response for my projects looks like this:

      {
      "id": "3ccf0f1b-dd3f-48d9-911a-ddf479078c37",
      "name": "Quantus Tasks",
      "description": "Quantus Tasks Desktop Application",
      "license_key_type": "alphanumeric_32",
      "created_at": "2019-05-12T10:45:42.089406Z",
      "updated_at": "2019-05-12T10:45:42.089406Z",
      "_links": {
        "self": {
          "href": "http://localhost:8000/v1/applications/3ccf0f1b-dd3f-48d9-911a-ddf479078c37"
        },
        "licenses": {
          "href": "http://localhost:8000/v1/applications/3ccf0f1b-dd3f-48d9-911a-ddf479078c37/licenses"
        },
        "templates": {
          "href": "http://localhost:8000/v1/applications/3ccf0f1b-dd3f-48d9-911a-ddf479078c37/templates"
        },
        "apikeys": {
          "href": "http://localhost:8000/v1/applications/3ccf0f1b-dd3f-48d9-911a-ddf479078c37/apikeys"
        }
      }
      }

It still has the ID field in there for cases where the client needs to store the id itself but it should not be used to template URI's for related resources, the links are there for that.

<comment><USER52> I've always been a bit undecided on this. I can see some obvious upsides, but on the other hand (apart from the downsides mentioned in the article and elsewhere) you've added 500 bytes to this entity for functionality that's only useful to the developer. Is the ability to click around in a HAL browser instead of a Swagger document worth the verbosity? Is there an argument that we might produce clients that can meaningfully deal with new links being presented without a developer being involved? I'd be surprised if that was realistic.

<comment><USER51> Yes, 500 bytes extra but it's not only for the developer discovering the API in a browser. If the client developer is exploring the API and then manually implementing an API client something is not right.

Hal clients for this use case do exist. you point them to an entrypoint and they can discover and generate the necessary code/methods for interacting with the API.

For example: [https://github.com/pezra/hal- client](https://github.com/pezra/hal-client)

</comment></comment></comment><comment><USER53> I think I am missing the core concept here. This still uses IDs, only now you have to grep them out of a URL construct instead of just getting them directly?

I don't get the intent at all here, but I have a suspicion whatever problem this tries to solve is better solved by UUIDs or by doing nothing out of the ordinary.

<comment><USER46> The URL doesn't contain the ID, it _is_ the id. If you stop treating the URL as an opaque string but start parsing things out, you are definitely not getting any benefits.

One benefit of using urls as ids is that it no longer is just an id, it also describes where you can get it's representation.

</comment></comment><comment><USER54> Reminds me of HATEOAS see here: [https://en.wikipedia.org/wiki/HATEOAS](https://en.wikipedia.org/wiki/HATEOAS)

Also RDF endpoints usually use resolvable URI's to connect concepts and objects with each other.

</comment><comment><USER55> Is the main reason for this is that crawlers could figure out and index more by themselves?

</comment><comment><USER56> No one thinks twice about using links for images. You wouldn't make an API that specified images as "image id 2345, which the client can find at /images/{id}"

<comment><USER57> I would and have…. If you're in a position to specify that images can consistently be identified by a small key, that's nice and simple. Go for it.

<comment><USER30> Key of 10 symbols from (latin alphabet + numbers) have 3656158440062976 possible combinations.

<comment><USER57> That's a fun fact, but what does it have to do with this?

</comment></comment></comment></comment><comment><USER58> This is all assuming REST is still a good idea.

</comment><comment><USER59> Why on earth would one trade off a short, static unique identifier for a potentially long, dynamic "link" that essentially binds all data to some crappy API that will be outdated in a few years? Is it really _that_ hard to use keys?

</comment><comment><USER60> In micro services world this makes perfect sense. In the legacy land - this is slightly tricky as dependent application (where our foreign key points to) may or may not be in services world. But I get the idea.

<comment><USER60> I don't know what made my above comment to get negative votes (-3). I was sharing an honest opinion here.</comment></comment>


Show HN: Pointless Blog Idea #99 Programming Everywhere. - <AUTHOR> http://www.programmingeverywhere.com

<comment><AUTHOR> Eventually there might be real pictures of people actually coding in strange locations.</comment>


Show HN: A command line program for practicing/learning regular expressions - <AUTHOR> https://github.com/Liniarc/regexProgram

<comment><USER2> Cool idea but doesn't build on my Mac</comment>


Air Force wants cryptographic security for iPhones, Android - <AUTHOR> http://www.networkworld.com/community/blog/air-force-wants-cryptographic-security-iphone

<comment><USER2> It's about time we looked at GPL'ed implementation standards for Android call and text encryption, especially considering the trailing and security through obscurity approach by GSM networks.

<comment><USER3> Somehow I find it difficult to believe that would be included on any carrier- approved Android build, let alone enabled by default. OSS & client-side (i.e., no backdoors) encryption is the government's worst nightmare.

</comment></comment><comment><USER4> Maybe while they are at it, they can convince their friends that crypto backdoors are bad for everyone.

<comment><USER5> What's the subtext behind this comment? I don't see what specific point you're trying to make. I could guess, but I'd rather just hear it directly from you.

<comment><USER4> The recent buzz about NSA, or whichever three-letter agency it was, pushing for crypto backdoors. And by friends, I just mean other people in government/military/intelligence.

I don't really have a point here, just a thought that popped in my head.

<comment><USER5> The recent buzz about DoJ putting backdoors in OpenBSD's IPSEC stack was, even if you buy the totally unsubstantiated and bogus buzz, in order for DoJ to monitor _their own networks_ ; ie, even if you believe the crazy people spreading that FUD, there's no claim that there's a public-facing backdoor in OpenBSD.

It doesn't seem reasonable to me that we should spend months up in arms about the government backdooring projects every time someone 5 degrees of separation away from a major project makes a claim.

<comment><USER4> I didn't mean the OpenBSD alleged backdoors. I meant future backdoors that would be required by law. I remember reading a news article about that recently (might have been a few months ago).

</comment></comment></comment></comment></comment><comment><USER6> This is a pretty neat company making encryption apps for android: <http://www.whispersys.com/>

<comment><USER7> This article totally reminded about whisper systems. I'm downloading their phone and text replacements now and can't wait to try them out.

</comment></comment><comment><USER4> <http://www.cryptophone.de/>

This German company has been selling commercial phones enhanced with their crypto software (for SMS and voice) for a while now.</comment>


GlobalFoundries Announces Early 7nm Availability, Huge Gains Over 14nm FinFET - <AUTHOR> https://www.extremetech.com/computing/250936-globalfoundries-announces-early-7nm-availability-40-improved-performance-14nm-finfet <comment><AUTHOR> The next version of Ryzen will be based on 7nm [1].

Will be interesting to see how AMD uses the benefits of this process. I guess they could potentially add another CCX complex to the die, so the 2018 flagship Ryzen 7 could be a 12 core part.

[1] [http://cdn.wccftech.com/wp-content/uploads/2017/05/AMD- Zen_3...](http://cdn.wccftech.com/wp-content/uploads/2017/05/AMD-Zen_3.png)</comment>


Show HN: Neh – Execute any script or program from Nginx location directives - <AUTHOR> https://bram.dingelstad.xyz/blog/introducing-neh/ <comment><USER2> And we've come back round full circle from CGI scripts, although separating out headers and body on different fds sounds neat

<comment><USER3> Many things we've dispensed with long ago seem to be forgotten and the younger coders are learning for themselves the hard way. Aka the same way we did.

<comment><AUTHOR> One of the things I'm wondering however: How popular is CGI if I don't find it with the query "run script on nginx location directive".

<comment><USER4> Nginx probably somewhat-deliberately has FastCGI but not regular CGI for a number of reasons.

CGI has process-per-request overhead.

CGI typically runs processes as the user the webserver is running as; said processes can generally read and write to the unsandboxed address space of the calling process (such as x.509 private certs).

Just about any app can be (D)DOS'd. That requires less resources with the process-per-request overhead of CGI.

In order to prevent resource exhaustion due to e.g someone benignly hitting reload a bunch of times and thus creating multiple GET requests, applications should enqueue task messages which a limited number of workers retrieve from a (durable) FIFO or priority queue and update the status of.

Websockets may or may not scale better than long-polling for streaming stdout to a client.

<comment><AUTHOR> Interesting and really informative! Thanks for sharing!

</comment></comment></comment></comment></comment><comment><USER5> "When I searched the first time, most of the answers that I found revolved around using things like "FastCGI with PHP" . I wasn't gonna use PHP to call a bash script, that would be overdoing it probably."

FYI. You don't have to use PHP to make use of FastCGI. You can simply use something like fcgiwrap (apt-installable on debian) and use it in Nginx.

</comment><comment><USER6> I want to scream out: Why the f would you want to do that?

<comment><USER7> Deploy script triggered from a third party webhook?

<comment><USER8> Blatant self promotion, I built a server in Go to do exactly this with GitHub webhooks... I make very extensive use of it.

[https://github.com/donatj/hookah](https://github.com/donatj/hookah)

</comment></comment></comment><comment><USER9> This is awesome! Thanks for sharing it. I, too, have unintentionally recreated existing technologies (a unix util, pass, in my case).

I recently built something similar with node + bash scripts. Node basically just verifies the webhook, runs a bash script, on failure it rolls back and emails me.

</comment><comment><USER10> Why are you recreate CGI? over nginx?

<comment><USER10> STDIN/STDOUT and header at environment variables is definitely CGI.

</comment></comment><comment><USER11> this is just cgi right. you don't need lua

</comment><comment><USER12> What could possibly go wrong?

</comment><comment><USER13> Another curl | bash installer that is not even tied to a commit :(

<comment><AUTHOR> Good point, I'll also try to move it into a git tag like the comment down here also suggests!

<comment><USER13> Thanks! I'm really not a fan of the trope of piping stuff directly into running it as root for obvious reasons.

Have you seen zerotier (the software)'s idea too? They ask you to import a GPG key and verify it before chaining it into a |sh or |bash.</comment></comment></comment>


Rubymonk is back live again - <AUTHOR> https://rubymonk.com/ <comment><USER2> That's a great site for learning Ruby!</comment>


Why Some Languages Sound Faster Than Others - <AUTHOR> http://blog.expectlabs.com/post/43157049869/why-some-languages-sound-faster-than-others

<comment><USER2> The conclusion that most languages "convey the same amount of information in exactly the same amount of time" is interesting. I wonder if the information density per syllable or syllables per second are important factors for determining which languages are easier to learn.

<comment><USER3> It also feels like BS to me. Multiplying the information density of the average syllable with the average number of syllables spoken per second should give the amount of information conveyed per second. The claim is that this is constant, but the table given does not support this.

Let's make that calculation:

      Japanese: 0.49 * 7.84 = 3.8

      Spanish : 0.63 * 7.82 = 4.9

      English : 0.91 * 6.19 = 5.6

      Mandarin: 0.94 * 5.18 = 4.9

That would make English carry 47% more information per second than Japanese.

<comment><USER4> I saw another similar but broader study a while back that singled out Japanese as the (low) outlier, and a claim that speakers of Japanese make up the shortcoming via facial expressions.</comment></comment></comment>


Illustrator CS5 gains HTML5 chops - <AUTHOR> http://blogs.adobe.com/jnack/2010/09/illustrator-cs5-gains-html5-chops.html

<comment><USER2> "I'm curious to see whether this news makes it onto the Mac sites that've beaten Adobe up for a perceived lack of enthusiasm about HTML5 (tough, as it just doesn't fit that sterile, stupid narrative). The funny thing is that these changes build on the SVG support that Illustrator has been shipping for ten years. Sometimes it just takes a while for the world to catch up."

Adobe's not helping themselves by being so openly hostile towards Mac sites. Not sure why they would post anything like that in a company blog.</comment>


Richard Stallman's view on eBooks. - <AUTHOR> http://www.guardian.co.uk/technology/2012/apr/17/sharing-ebooks-richard-stallman

<comment><USER2> Not surprising - and he's right in a number of ways.</comment>