Checked C - <AUTHOR> http://research.microsoft.com/en-us/projects/checkedc/ <comment><USER2> This seems to be a successor to CCured from 2005, a project partially funded by Microsoft. [1]

The general idea is straightforward: _" The unchecked C pointer type_ * _is kept and three new checked pointer types are added: one for pointers that are never used in pointer arithmetic and do not need bounds checking (ptr), one for array pointer types that are involved in pointer arithmetic and need bounds checking (array ptr), and one for pointer types that carry their bounds with them dynamically (span). "_ So this is really a new language derived from C, to which programs can be converted.

This is basically a good idea, but it's only useful if pushed hard by somebody like Microsoft. People won't convert without heavy pressure.

[1] [https://www.cs.virginia.edu/~weimer/p/p477-necula.pdf](https://www.cs.virginia.edu/~weimer/p/p477-necula.pdf)

<comment><USER3> Being pushed by Microsoft could be exactly the reason _not_ to convert, for many people. Especially when there is no shortage of alternatives that are backed by a bit more benevolent entities (Rust, and many other less known variants).

<comment><USER3> In reply to myself: The times are changing indeed. It seams that HN-ers started liking Microsoft. Whenever I post some concern, even if only mild, there is first a few upvotes, and then a bunch of downvotes.

Microsoft became the darling of the community, OR, in addition to embracing open source, they embraced voting ring tactics. These are two explanations I have, maybe there is another. Maybe my criticism really was obnoxious...

<comment><USER4> Maybe it's just because yes, we all remember the 90s. But today is not necessarily the 90s. It was a lot more recent that Google was a relatively benevolent company, and we've all seen how that's changed.

And the thing about open source projects, is just that. They're open source. If the wider community takes hold of them, there's not much Microsoft can do. Because then you just see a fork.

You don't have to be a fan of Microsoft to simply appreciate the contribution to open software, as it is.

<comment><USER5> pff.. they are "open source" just because they want to attract developers, because without developers writing apps for their platform, Microsoft will die (as any other platform). They are still just money-makers and nothing else, there is no any idea except money behind their movements to Open Source world, otherwise they wouldn't take revenues from Android.

<comment><USER6> Everything you say may (probably is) true.

Now why does anything in your post _matter_?

<comment><USER5> Because it's important to distinct intention to contribute to open-source world and intention to use this world to make money.

<comment><USER7> It's sad to see that despite open source (or free/libre..etc) software being around for so long, people still don't get it that money and freedom are not mutually exclusive. I would argue that contributing to open source for business reasons is perhaps even more beneficial for the software and community than just doing it for a hobby or some philosophy because companies pay people to even work on stuff that is not exciting / interesting.

<comment><USER5> sad to see that people still thinks "it's sad to see" that somebody can have different opinion.

<comment><USER7> Huh? I acknowledge that you have a different opinion and I'm saddened by that opinion.

I respect your right to have a different opinion. I don't have to respect the opinion itself. Hope you can see the difference.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER2> I had a go at this problem, backwards-compatible safe C, back in 2012.[1] It was discussed on the C standards mailing list, and the consensus was that it would work technically, but was politically infeasible. What I proposed was not too far from "Checked C", but the syntax was different.

I'd defined a "strict mode" for C. The first step was to add C++ references to C. The second step was to make arrays first-class objects, instead of reducing them to pointers on every function call. When passing arrays around, you'd usually use references to arrays, which wouldn't lose the size information as reduction to a pointer does.

Array size information for array function parameters was required, but could be computed from other parameters. For example, UNIX/Linux "read" is usually defined as

        int read(int fd, char buf[], size_t len);

The safe version would be

        int read(int fd, &char buf[len], size_t len);

In both cases, all that's passed at run time is a pointer, but the compiler now knows that the size of the array is "len" and has something to check it against. The check can be made at both call and entry, and in many cases, can be optimized out. In general, in all the places in C where you'd describe an array with a pointer with empty brackets, as with "buf[]", you'd now have to put in a size expression.

You could do pointer arithmetic, but only if the pointer had been initialized from an array, and was attached to that array for the life of the pointer.

        char s[100];
        char* p = s;
        ...
        char ch = *p++;

Because p is associated only with s, the compiler knows what to check it against.

There was more, but that's the general idea. A key point was that the run-time representation didn't change; there were no "fat pointers". Thus, you could intermix strict and non-strict compilation units, and gradually convert a working program to strict mode.

This took less new syntax and fewer new keywords than "Checked C". I was trying to keep C style, adding just enough that you could talk about arrays properly in C.

[1] [http://www.animats.com/papers/languages/safearraysforc43.pdf](http://www.animats.com/papers/languages/safearraysforc43.pdf)

<comment><USER8> I've already been downvoted for this question, but I don't get the business case here. If you are worried about this, why not write code in modern C++ which has plenty of ways to make all sorts of issues like this safe ? Why stick to C at all?

<comment><USER2> C++ doesn't solve the problem. C++ papers over the problem with templates. You can still get raw pointers out of C++ objects, and for most APIs, you have to. The underlying language objects are still unsafe.

<comment><USER8> ok, so write C++ classes that don't let you access raw pointers. I mean I understand that C/C++ languages are less safe than, say, Java - but that is the whole point. The lesser safety gives you better performance. If you don't care about bleeding edge performance, you should probably choose Java or Python or some other language that is much more flexible and easier to use

<comment><USER2> _The lesser safety gives you better performance._

No. That excuse has been bandied about for years, but it's wrong, as we're now seeing as Rust gets better. C's problems with arrays come from lack of expressive power in the language. C doesn't even let you talk about array size in parameters.

Many of C's painful design decisions come from trying to cram a compiler into a PDP-11 with 128KB (not MB) of memory for a process. Global analysis on a machine that small while retaining reasonable compile times was hopeless. This is no longer a limitation.

</comment></comment></comment></comment></comment><comment><USER9> You know, some people seem to scoff at replacement Cs. I'm kind of one of them. I know my reason(s) though. It's not about other languages as much as C itself. I've been with it for awful long time now and I used to think I kind of know my way around it. I've changed that line of thinking, because I know it's not true. I make a lot of mistakes, especially considering memory. At least (almost all of) my code isn't public-facing.

Since I thought I knew C very well, I came to realisation (due to many memory bugs/leaks) that maybe that's not the case after all. What is it then? I can get performance out of it, lots of it (that's one thing I know to do, somewhat at least). That's when I questioned myself and started thinking that it's not that I know C (I don't, after 20 years or so), but that I am very comfortable with it and I don't want to change that comfort. C++ and 90's traumas and post 90's (STL) traumas had a lot to do with it. Now, I'm fishing out for newer languages that would replace C for me, Rust namely, but I'm still falling back to C all the time. Now, I'm thinking that that's just the way it is. I'm a C programmer and that's how it will stay. At least for a long while. I do and have used a lot (A LOT) of languages in my past, but my core is always C (also first language I've learned). I don't program anymore for a living (I do "creative stuff" in film and tv now), so that is now more prominent than any other time in the past. I do stuff for me only and I can pick and choose whatever I want to - yet, it's always C.

Sorry for the "rant".

<comment><USER10> This mirrors my experience. C is a drug man. It's bad but you can't stop. You know how to get shit done in C and it's _easy_ to think in. C is, IMO, something of a local optima for programming. Problem is, it's actually a relatively awful language, and I don't subscribe to the worse-is-better philosophy (though C may well be the best example of it).

Thankfully Rust gets my ML instincts going. I'm trying to use it more. It'll be nice not to be anxiously running my test suite under ASAN after every build.

<comment><USER11> Yeah but after sixty years of C, why should we trust an origanization like Mozilla? They've been thoroughly unwilling to come up with any sort of ANSI standard or anything, despite Rust being a reasonably mature language.

Google sought ECMA standardization when they took on Dart. Go language has an official specification, so someone could hypothetically re-implement it if they wanted to, and remain compatible Go projects.

Mozilla only wants Mozilla to be involved with Rust. They want everybody to use it in their systems, and have no input on where the language should go.

<comment><USER10> Huh? Anyone can submit an RFC: [https://github.com/rust- lang/rfcs](https://github.com/rust-lang/rfcs)

While Mozilla may not be the best organization, the Rust team seems much more willing to listen to their users than the Firefox team.

</comment></comment></comment></comment><comment><USER12> Interesting. I thought Microsoft has stopped liking C a while back. Remember complaining about C99 support in VS and getting a response about "Just use C++ compiler as a C compiler, you don't need C anymore". It took them until VS 2015 finally to support it.

<comment><USER13> Also the DDK (Windows Driver Development Kit) didn't support C++ in any meaningful way. If I remember correctly, all my drivers had to be written in C89.

<comment><USER14> C++ is supported in kernel space since Windows 8.

</comment></comment></comment><comment><USER15> The idea is nice (although old and tried more than once), but I'm pessimistic as it doesn't seem to be backwards compatible and requires a specific, new compiler. For legacy projects it's hard/impossible to change a toolchain/compiler and for the new projects one can as well use Rust or other modern language.

</comment><comment><USER16> Reminds me of Cyclone: [https://cyclone.thelanguage.org/](https://cyclone.thelanguage.org/)

Many Cyclone ideas made it into Rust.

I strongly prefer Rust.

<comment><USER17> You should look at their paper. They have an impressive survey of prior approaches including Cyclone, and they claim that their approach (if I understand them correctly) could allow you to do some things outside of unsafe blocks if implemented in C# or Rust.

<comment><USER18> I don't see any use-after-free prevention here from a skim of the paper, so this doesn't seem to address many of the most important benefits you get from C# or Rust.

Use-after-free is not a theoretical problem. All of the Pwn2Own vulnerabilities this year were UAF, for example.

</comment></comment></comment><comment><USER19> This clarifies the need for a more "rust-like" C. I hope something like this will flow into standard C...

<comment><USER20> I can't upvote this enough. I started to play with Rust a few months ago and I especially like their compile-time checks of the code. I don't see why C compiler vendors can't do the same thing. Imagine if folks like GreenHills or WindRiver adopt such a practice in their compiler. It would revolutionise their industry. IAR has MISRA-C checks in their compilers but that is not enough.

<comment><USER18> Because the C language is fundamentally hostile to Rust's safety features.

<comment><USER21> what about fail quick fail often

</comment></comment></comment></comment><comment><USER22> the obvious question: how does this compare to rust? it looks like rust and this aim to solve a very similar set of issues in more or less similar way ('static and dynamic checking'). i'd be very interested in a table that compares capabilities of both. of course there's a gigantic advantage of this being C, so in theory valid checked C would be valid C with all benefits of that.

<comment><USER18> Well, this isn't C: it's a different language that extends C. There's a big difference between that and just being C. In particular, valid checked C is not valid C, because checking requires using the language extensions.

Regarding the comparison to Rust, Rust prevents use-after-free, while this doesn't seem to from a skim of the paper. Use after free is one of the most, if not the most, common remote code execution security issues in C and C++ code nowadays.

<comment><USER23> > Use after free is one of the most, if not the most, common remote code > execution security issues in C and C++ code nowadays.

I'd love to see a citation on this. My gut feeling tells me buffer overruns and integer overflows are seriously in the running.

<comment><USER24> It is certainly "one of the most", even if it is not "the most".

<comment><USER23> I'd love to see a citation on this, as I asked for previously. Repeating the comment I replied to isn't a citation.

<comment><USER24> That is somewhere around asking for a citation if the sky is sometimes cloudy.

[https://web.nvd.nist.gov/view/vuln/search- results?query=use-...](https://web.nvd.nist.gov/view/vuln/search- results?query=use-after-free&search_type=all&cves=on)

Before getting too excited and claiming that it's only 1.3% of all CVEs or something, remember that it's 1.3% of _all vulnerabilities_. (Especially with the explosion of dynamic web languages, a lot of CVEs aren't really C/C++-related.) There's a power law to these things, so by the power law metric, it's not that far behind "buffer overflow" (6,500 entries), and ahead of the well-known "format string" (577), which is also certainly "one of" the most common C issues.

<comment><USER23> I'm looking specifically for remote code execution vulnerabilities, which is what the original comment was discussing, and which is a subset of what you posted.

And no, this is not like asking for citations for the sky sometimes being cloudy because the original comment didn't say "use-after-free sometimes leads to remote code exploit".

This is like asking for citations for a claim like "whenever the skies are cloudy it is due to acid rain more than any other reason". And a claim like that should be accompanied with some citations.

Let's have an honest discussion here, or don't bother, please.

</comment></comment></comment></comment></comment></comment></comment><comment><USER25> _It is a design goal to allow Checked C to be a subset of C++ too._

Interesting. In times when many people advocate a safe C++ subset, Checked C grows the other way, adding C++-compatible notation to represent the most vital things like smart pointers.

</comment><comment><USER26> Good timing for me, since I have been falling back to C for some personal projects. I keep looking at Rust, but I just don't have the time. It would be nice to leverage the experience I already have, and see what Checked C offers.

</comment><comment><USER27> This greatly lacks an overview as the specification[1] is very in-depth.

I kind of wonder if they're working on automatic conversion tools between C and checked C. At least for ptr<> this should be trivial. If a function does no pointer arithmetic with a * pointer and only uses it in function calls that take ptr<>, can be converted to a function taking a ptr<>.

[1] [https://github.com/Microsoft/checkedc/releases/download/v0.5...](https://github.com/Microsoft/checkedc/releases/download/v0.5-final/checkedc-v0.5.pdf)

</comment><comment><USER28> microsoft.com discussion: [https://news.ycombinator.com/item?id=11900009](https://news.ycombinator.com/item?id=11900009)

<comment><USER25> It would be nice to merge these two submissions' comments.

</comment></comment><comment><USER29> Language extension for maintenance of legacy application sounds a little bullsh1t to me.

0) If the application needs checks on anything (at the cost of performance) then higher level language (like C++) should be chosen at design time. No use for new application. 1) Existing applications will NOT port directly. Real- life applications are tightly coupled with supported compiler(s), so the compiler would need the update. Errors/exceptions (like overflows) would need handling and changes in logic. It could only deny read/write from illegal area, but without the feedback. The speed is also a major thing. Boundary check could possible prevent some bugs, but the performance will drop dramatically (example: commonly used libs like OpenSSL).

One use case I see is to add an extension (like GCC's for instance) for an existing compiler which does this. User could build a slower debug application and spot the silent errors during testing. An implementation thing, not the language extension.

</comment><comment><USER30> I wish they supported namespaces.

<comment><USER31> +1

</comment></comment><comment><USER32> So they couldn't be bothered to contribute that directly back to LLVM/Clang or am I missing something?

<comment><USER33> Baby steps.

The phrase " _couldn 't be bothered_" is assuming a lot of bad faith on Microsoft's part. While I would agree that in times past MS didn't deserve the benefit of the doubt, these days they're a different company.

With no special insight into their reasoning, I think the more likely answer to the question, "Why didn't they contribute this upstream?" is probably "Give it time."

</comment></comment><comment><USER34> Amazed at the amount of open source coming out of MS these days, very nice !

</comment><comment><USER35> So databases and browsers are "system software" now?

</comment><comment><USER8> why? I mean if you think you really need checked C, then why not just use C++?

</comment><comment><USER36> Does it include telemetry calls?

</comment><comment><USER37> [https://en.wikipedia.org/wiki/Smart_pointer](https://en.wikipedia.org/wiki/Smart_pointer)

</comment><comment><USER5> Microsoft style - be too closed to adopt existing solutions, always invent own ways/standards.

</comment><comment><USER38> I've written lots of C and never had problems with buffer overruns, bounds checking, double frees, and other memory issues. Typically at a glance in one's code, I can tell when behavior may be undefined, and once someone has a little experience, they can avoid undefined behavior altogether. Why does so much work go into fixing these problems? In other words, what are some examples of use cases of a stricter language like this, that would be too complicated for human eyes to quickly verify?

<comment><USER39> Here you don't check the return value of calloc():

[https://github.com/AndrewBelt/bored/blob/master/src/map.c#L3...](https://github.com/AndrewBelt/bored/blob/master/src/map.c#L33)

and then access it:

[https://github.com/AndrewBelt/bored/blob/master/src/map.c#L4...](https://github.com/AndrewBelt/bored/blob/master/src/map.c#L44)

Here if realloc() fails, you'll have a memory leak and, again, accessing NULL later:

[https://github.com/AndrewBelt/bored/blob/master/src/priq.c#L...](https://github.com/AndrewBelt/bored/blob/master/src/priq.c#L28)

There is also integer overflow: alloc is int, so if it becomes greater than 2^31-1, it may wrap around [I think signed int behaviour in C is undefined in this case], and you'll allocate fewer bytes than needed, leading to buffer overflow.

<comment><USER40> Well, to be honest, very few programs are able to orchestrate >2GB allocations correctly when complied to 32 bit binary, like Visual Studio linker is not aware of >2GB sizes by default (one need to /LARGEADDRESSAWARE flag for it), which was a trouble for modern browsers because linker was unable to fit everything in limited virtual address space.

And another to be honest, very few programs on desktops/mobile are actually checking return values of malloc/calloc, because of amount of data that program operates is usually much smaller than amount of RAM available. It's sure a case for embedded, but you simply usually don't use malloc for embedded.</comment></comment></comment>


Postman - a JavaScript message bus - <AUTHOR> http://github.com/aaronpowell/postman Postman is a JavaScript library & npm package which allows for cross-component messaging like traditional pub/ sub libraries but without the reqiurement on a message to be published after all the listeners are attached. <comment><USER2> Could someone please explain me what's the point of this? I can't imagine any serious use case.

It looks inefficient (uses arrays instead of linked lists/queues, so every cleanup requires full array rebuild), lacks any sort of message ordering guarantees (or notifications of lack thereof), lacks queue length limits (only time-based expiry and custom cleanup functions seeing only the value of message are provided) and so on.

Moreover, I don't get the following:

        dropByDate = (date, msgs) ->
            msgs.reduce (x) ->
                x.created < date

I believe msgs is an array (cache[name].history), but IIRC Array.reduce does not work like this, it's Array.filter that does.

<comment><AUTHOR> I wrote this because the application I'm working on has dozens of small JavaScript components loaded, some of which rely on messages published by others. Some of them are invoked in-place, others are invoked as part of dom ready events so ensuring that the handlers are added before the messages are raised can't be done. Message ordering isn't important and since it's intended for asynchronous programming it shouldn't be important.

As for linked lists vs arrays I'm not convinced that a linked list would be a better performer than an array for iterative access (which is a rather crucial part of the library).

The reduce thing is a bug (I've chucked it on the issue register) as well as a feature request for only keeping a finite message limit.

</comment></comment><comment><USER3> No, it's a CoffeeScript message bus.

<comment><AUTHOR> Well yes, but there is a JavaScript version in the github repository so you don't need to know what CoffeeScript is or anything</comment></comment>


The Subway Doesn't Have to Be Hot and Gross - <AUTHOR> https://www.vice.com/en_us/article/ev8jye/no-the-subway-doesnt-have-to-be-insanely-hot-and-gross <comment><USER2> 20 years ago, the MTRC in Hong Kong started to install platform screen doors to seal off the platforms and reduce their air conditioning bill as most of the cool air was of course just going into the tunnels. That investment paid for itself within a few years.

Evacuating the heat from the train is another issue that must be addressed but it's far from being an unaddressable one and there are already many examples of other cities implementing workable solutions.

Having doors installed along the platform has a number of advantages beside air conditioning: increased safety (no more suicides and accidents), more platform capacity since people can get right to the edge of the platform, potential increase in network capacity since trains can enter the station faster as they don't have to slow down early to enter the platform at low speed to avoid passengers accidents.

Older networks like London, Paris and New York have a much harder time implementing these measures as they are often very deep and their infrastructure are old and quite vast, but they each have projects to tackle these issues, although in the case of New York, the cost will probably slow down adoption (not least because of the crazy Union requirements).

<comment><USER3> The problem with doors in New York in particular is that not all generations of rolling stock have doors in the same location. Unlike MTRC, where one line has its own rolling stock and there is no interoperation between different lines, many services, each with different door positions, can utilize the same platforms. And basically the only way to have a door configuration compatible with all rolling stock is to not install any doors at all.

You could replace the rolling stock, but all of it is in good operating condition, and the last of the oldest cars with non-compatible doors would be retired in the 2030s.

Air conditioning is also a huge challenge; traditionally, New York's subway has been cooled using the piston effect of trains, with frequent grates open to the surface to draw in air. With air conditioning those large, frequent openings are now a curse.

<comment><USER4> The IRT and BMT Eastern Division all use cars that have doors at the same place, so that's not an excuse to not try platform doors. You could make the test station one of the L train stations that's going to be closed for two years and install them at a super leisurely pace. (The L is basically completely isolated from the rest of the system, and already requires special rolling stock for CBTC. And it's going to be closed for two years for other repairs.)

Even if varying door locations were the problem... Tokyo has many lines that share rolling stock among 3 or even 4 separate rail companies, and they still have platform doors. There are just a lot more doors in the station than on each train.

There simply is no interest or money for platform doors in NYC. Even though people fall onto the tracks and are killed, even though many stations suffer from capacity problems because there aren't enough safe places to stand, even though people holding train doors delays every train multiple minutes a day... we're simply allergic to the concept. I've never even heard it seriously proposed.

<comment><USER3> The major IRT lines save for the 7 operate mixed fleets of NTT and R62/A equipment, none of which share door positions IIRC. The Eastern Division still uses old rolling stock like R42s from time to time. The last time they tried getting rid of cars prematurely, the R179 order came in late and they were forced to run what cars remained had more aggressively, degrading reliability.

> You could make the test station one of the L train stations that's going to > be closed for two years and install them at a super leisurely pace. (The L > is basically completely isolated from the rest of the system, and already > requires special rolling stock for CBTC. And it's going to be closed for two > years for other repairs.)

This actually was a proposal. It was recently killed in favor of bringing elevators to Union Square, a major subway complex that is not ADA accessible. Which is really why they haven't caught on as a serious engineering proposal; the list of things that would be much better value for money is long, such as systemwide ADA accessibility, CBTC signalling, replacement of rolling stock, refurbishment of dilapidated, water-damaged stations, etc. You could easily come up with $50B worth of upgrades, extensions, etc. before platform doors became a priority. And they're not even that feasible.

> There are just a lot more doors in the station than on each train.

Got a source for this? This is intriguing because I've never heard of something like this. But this also introduces the complexity that the right doors have to open at the right time, lest a blind person walk into a gap between trains and die. Which is a lot to ask from an agency that can barely maintain something as mundane as elevators and escalators.

<comment><USER5> > The major IRT lines save for the 7 operate mixed fleets of NTT and R62/A > equipment, none of which share door positions IIRC

Do they not? The R62 and R142 cars are both the same number of doors and of the same length [1] [2], and the moving platforms at some stations would, I think, require the doors be in approximately the same spot, no?

> The Eastern Division still uses old rolling stock like R42s from time to > time.

Yes, but the R42 and R143/R160 have the same overall length and door count (and the spacing appears to be the same as well) [3] [4]

As an aside: it's quite frustrating that the measurements given on the datasheets are of varying frequency.

[1] [https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r6...](https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r62.jpg)

[2] [https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r1...](https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r142.jpg)

[3] [https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r4...](https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r42.jpg)

[4] [https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r1...](https://www.nycsubway.org/perl/caption.pl?/img/cars/sheet-r143.jpg)

<comment><USER3> They do not.

In R62s, doors are parallel to each other on each side of the car. [1]

However, it was found that because passengers like to crowd at doors, passengers wishing to exit from either side would just crowd in the same place.

To ease crowding, the NTTs have wider, offset doors, so that not everybody is standing in the same place [2]

The gap fillers at Union Square are very long, which is why they can line up with multiple door positions. [3]

[1] - [https://en.wikipedia.org/wiki/R62_(New_York_City_Subway_car)...](https://en.wikipedia.org/wiki/R62_\(New_York_City_Subway_car\)#/media/File:R62_interior.jpg)

[2] - [https://en.wikipedia.org/wiki/R142A_(New_York_City_Subway_ca...](https://en.wikipedia.org/wiki/R142A_\(New_York_City_Subway_car\)#/media/File:Empty_subway_in_NYC.jpg)

[3] - [https://i.ytimg.com/vi/rHyfbrJ8ge4/maxresdefault.jpg](https://i.ytimg.com/vi/rHyfbrJ8ge4/maxresdefault.jpg)

</comment></comment></comment></comment></comment></comment><comment><USER6> Regarding the heat generated from braking. I was surprised to find out that in our (very small) subway system the stations are higher than the rest of the track. This slows down the train as it is approaching the station and helps it regain speed when it leaves the station. A quite obvious idea, but must admit I might have not thought about it.

In some cities they are building district cooling [1] (comparable to district heating). Might be quite a difficult solution in densely built areas of course.

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

<comment><USER7> Can passengers feel a mild roller coaster effect, or is the incline too small for that?

<comment><USER8> I would assume the incline would be impossible without seeing the horizon, because the car also accelerates. I guess you mean the increased gravity feeling at the bottom of the track?

<comment><USER7> Right. I traveled once on a long-distance bus line that acted like a zero- gravity plane for a split second, as it went over a bump in the road. Just wondering if the experience would be comparable :)

</comment></comment></comment></comment><comment><USER9> "the majority [of heat comes] from the train hitting the brakes as it pulls into the station, an intense friction that gives off an exorbitant amount of warm air."

I wonder if regenerative brakes can be installed (or are already installed...)

<comment><USER10> And/or platform doors:

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

Seems like they'd keep heat from the train from making its way onto the platform. And if platforms are air-conditioned, they'd keep that air from escaping into the tunnels.

And of course they can also help with safety.

<comment><USER3> Doors only work if they can line up with every single train that services said platform. Unfortunately, not all trains share door positions, and most platforms will see a mixed fleet of trains. The new trains have consistent door positioning, but the old ones are still in good working order and aren't due for retirement until late 2020s-early 2030s.

<comment><USER11> It is still doable, you can start by splitting the running stock by similarly aligned doors run them on few line and start with the few lines which are now already aligned.

Realistically by the time you are even close to half the 470 stations it will be late 2020's anyway. Then you can aim for full coverage as the stock is deprecated.

It is more likely the $1-2 million per station cost is not high priority as say CBTC which will improve revenue as it increases capacity.

<comment><USER3> The problem is that none of the lines except two of them are separated enough. Separating them to the degree required for this to work is not possible, because the crazy interlining is the only way to provide many trips in a patchwork system that was originally three competing subways; many transfers would not be available, and the remaining ones would not be able to handle the resulting transfer volume. It would also not be desirable, because right now reroutes are commonly used to maintain service in case of problems or maintenance; doors restricting fleets to lines would reduce operational flexibilty.

The problem is also too large to segregate. We are talking about a third of the current fleet that is not compatible with new train door placements. Even after the oldest of these are retired with projected future train orders, it will be about a tenth of the fleet, larger than the entire Boston T rapid transit fleet.

</comment></comment></comment></comment></comment><comment><USER12> Anyone who has taken the subway (MRT) in Singapore knows that stations definitely don't need to hot and gross. It maybe different because we don't need full HVAC but rather only air conditioning, but taking public transport has only ever been pleasant (except when it breaks down).

Maybe some principles can be applied to other subway systems?

<comment><USER13> [https://en.wikipedia.org/wiki/Mass_Rapid_Transit_(Singapore)](https://en.wikipedia.org/wiki/Mass_Rapid_Transit_\(Singapore\)) vs [https://en.wikipedia.org/wiki/New_York_City_Subway](https://en.wikipedia.org/wiki/New_York_City_Subway) \- not surprising we learned a lot in 80 years of operating subway systems.

</comment></comment><comment><USER14> Curious to hear from someone who may know more about HVAC than me:

Why don't subway stations simply install giant industrial mini-spit-style air conditioners in these stations? It doesn't seem particularly hard to rout a few dozen tubes of coolant down to a station while keeping the compressor and expelling heat outside.

<comment><USER15> > It doesn't seem particularly hard to rout a few dozen tubes of coolant down > to a station while keeping the compressor and expelling heat outside.

It's hard when you're spending $90.4M to install 3 elevators.

That said, while mostly it's just an annoyance, the heat really is a hazard at a handful of stations; people are regularly blacking out at union square while waiting for the L.

<comment><USER16> Any ideas why its so expensive? For 90m you could get a whole new tram line...

</comment></comment></comment><comment><USER17> The other day I calculated that the subway trains in Warsaw must give off as much heat during braking as a 70-100kW heater working continuously.

And that's a conservative estimate given that I assumed the interval between trains going a given way to be 5 minutes - during the rush hour they're twice as frequent.

Not to mention the collective body heat of a few hundred people waiting on the station which is (!) of the same order.

</comment><comment><USER18> The Tokyo subway is both air-conditioned on the platform (in places) as well as in the cars and has been for decades.

China's subways are all air-conditioned.

</comment><comment><USER19> NYC city subway is one of the low points of the city.

On the other hand, it has this cinematic charm that I like as a tourist. But if I was going to work everyday and seeing this neglect, I'd rather had some renovations done.

</comment><comment><USER20> Why do you need AC when you can turn it into a spa? [https://www.youtube.com/watch?v=agUF_53fmyw](https://www.youtube.com/watch?v=agUF_53fmyw)</comment>


I slowly laid off 60% of my colleagues on Wall Street - <AUTHOR> https://news.efinancialcareers.com/uk-en/3001858/laying-off-bankers <comment><USER2> >"regular layoffs are necessary for this ecosystem"

>"I try to be as unemotional as possible"

Allow me to propose that a corporation shouldn't be structured in this way. Obviously a large bank is operating with a much more complex business model when compared to a small business that unclogs people's toilets, but the plumber's business should in theory not require any layoffs. It should be possible for a lean team to operate forever in a very humane manner.

Instead we have this pooling of capital and contracts in the hands of inefficient mega corps. The corps scoop up pretty much any worker they can when times are good, and then lay them off arbitrarily when the managers need to meet some KPI.

This is inherently unhuman and a waste of time and money. The laid off workers would normally be able to go innovate and start their own shop, but the big corps have locked up all the contracts and clients.</comment>


How to save the princess in 8 programming languages - <AUTHOR> https://toggl.com/programming-princess <comment><USER2> I don't really get it. I guess the JS one is kinda funny but maybe I don't deeply understand these other languages enough to get the joke.

I didn't even get the C one. Is it saying it's too powerful?

<comment><USER3> Read here: [https://en.wikipedia.org/wiki/Null- terminated_string#Limitat...](https://en.wikipedia.org/wiki/Null- terminated_string#Limitations)

I on the other hand do not get others than C. Especially Java one, and I've done a lot of Java so far.</comment></comment>


Fix the versioning - <AUTHOR> https://github.com/jashkenas/underscore/issues/1805 <comment><USER2> I am concerned the primary purpose of this being on the frontpage is shaming someone.

I'm a big fan of semver, but I also test whenever I do a rm Gemfile.lock; bundle install (I've only managed a fairly small nodejs app in production, but I'd be surprised if people really don't test something like that). So he did something we think is bad -- but plenty of beginning engineers do this all the time, and while the discussion on github is appropriate, I'm not sure it belongs here on HN. People shouldn't be afraid of making something useful (as underscore is) because of the potential for extremely public shaming.

<comment><AUTHOR> This is the most depended upon node module on npm, this is not some beginner engineer - I think this belongs here.

<comment><USER2> If the purpose is to alert people to perhaps subtle bugs in their code, then clearly it's relevant to the engineers here.

But if your point is that we should publicly highlight mistakes (or things we don't like) in packages because we expect people to do better... then I guess I should step out of this conversation. I don't want to talk highschool about someone building cool things.

<comment><USER3> The connection between a project's developers and its community is noteworthy and worth discussing.

As a developer, how you treat your user base is relevant, and has a real impact on the value of the thing you have produced. We have successful projects whose leaders vary wildly in style, from Linus's approach to kernel development to projects that delegate final code control to community contributors.

Talking about the human elements that factor in to technology has merit; talking about the best ways to handle a project's community has merit. It's not "talk[ing] highschool".

</comment></comment></comment></comment><comment><USER4> This feels like an overly abrasive response that makes me seriously question whether using Underscore moving forward is a good idea. I really hate to say that because I think Jeremy's projects are awesome.

This is the most depended on module on npm. Why are you so intent on alienating the package consumers? IMO, having a version 47.0.0 and such doesn't seem all that terrible to me, and is still just as human readable. Other groups are doing it and it's working just fine (ie Chrome).

<comment><USER5> _...having a version 47.0.0 and such doesn 't seem all that terrible to me..._

What would the effect of that be? Since few people are silly enough to use the ">=" operator in _package.json_ , a popular package with that many "breaking" changes is effectively going to be pinned at 46 different points. I imagine we'd start to see some of the same entitled whinging we see exhibited here, but in the opposite direction. "Why do you have so many major releases? It means I have to re-release my packages constantly."

<comment><USER4> That's a fair point. I guess a better solution in my mind is teaching people to be more responsible with their package.json file and consumption of packages (ie reading changelogs), but that's not jashkenas' problem, nor should it be.

<comment><USER5> Actually I think he's done quite a bit of teaching along those lines in the last three days. Several students seem unhappy with the lesson...

</comment></comment></comment></comment><comment><USER6> 1) Semver is hard. I've got publicly used libraries with millions of downloads and sometimes people use it in ways I don't expect and this results in breaking backwards compatibility. Most large projects aren't, or can't be true semver. Take for example Rails. This is a great discussion over an area over why breaking semver may be better than keeping it in one case: [https://github.com/rails/rails/issues/16497](https://github.com/rails/rails/issues/16497)

2) Breaking semver sucks, and I go hulk rage mad when my shit breaks.

<comment><AUTHOR> Totally agree, however I feel there is a difference between choosing to break semver for a specific reason rather than a complete disregard for it.

Semver should be based upon the public API - if a dependent module is using undocumented stuff then they should pin the version down.

</comment></comment><comment><USER5> It takes a certain _chutzpah_ to leave the sort of comments one sees on this issue and the similar one for Backbone. The author hasn't made a secret of his versioning policy. If you have a broken module, you shouldn't have used [EDIT: actually "~" would have been fine] "^" or (my favorite) ">=" as a semver operator when depending on this module on which you depend for free. Anyway, with a decent test suite, surely a modicum of (automated) testing has already identified the pinning that should take place?

<comment><AUTHOR> >The author hasn't made a secret of his versioning policy.

No one is going to see that unless they go looking for it though

>you shouldn't have used "~", "^"

That is how the npm ecosystem works, and in any case the issue arose from dependencies that in turn depended on underscore and thus are not under my direct control.

> Anyway, with a decent test suite, surely a modicum of (automated) testing > has already identified the pinning that should take place?

My particular issue is in a new project I could not install several dependencies as npm downloaded the newest compatible version which was supposedly 1.7.0 - the only way to fix this is to manually create a lock file.

>you depend for free.

True, and I'm tremendously grateful for all the work that has gone into it and it would be a massive shame if that work was for nothing if a continued disregard for semver forces people to switch to lodash.

<comment><USER5> _...dependencies that in turn depended on underscore..._

Do you imagine that the maintainers of all these dependencies are going to catch any fraction of the hell that jashkenas seems to be catching for this? It's just as much their fault as it is his. Why don't they pin and test?

<comment><AUTHOR> Because that is not the convention in the ecosystem - npm mandates the use of semver - if you follow it this can't happen. If you do what you say and pin it down to an exact version then you would have to release an update every week consisting of just a version bump.

<comment><USER5> Don't stop there: think it all the way through! Breaking changes lead to version bump releases, whether the module follows semver or not.

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

Do you mean to imply that breaking-change frequency should stay below some particular maximum value? That argument is completely unrelated to the use or disuse of semver.

</comment></comment></comment></comment></comment><comment><USER7> The title-as-submitted ("Underscore.js author breaks 100s of modules because of a disliking of semver") is unnecessarily personalizing and editorializing. I'd suggest a title of just the facts: "Underscore.js 1.7.0 breaks modules by rejecting semantic versioning". (The native title, "Fix the versioning", contains insufficient detail to convey either the important warning-to- Underscore-users nor reflect the issues discussed.)

This issue highlights an interesting philosophical split.

I suspect the same minimalist, intentional aesthetic that has made Ashkenas's projects so beloved equally drives his dislike of version-inflation, whatever its convenience is to downstream systems on autopilot.

<comment><USER8> > The native title, "Fix the versioning", contains insufficient detail to > convey either the important warning-to-Underscore-users nor reflect the > issues discussed.

Incidently, this is the title the mods chose. Can anyone guess how many spots the link dropped on the front page after that change?

</comment></comment><comment><USER9> The only major version bump that matters is the one from 0 to 1. After that, the project is better served if its maintainers do not fetishize major version numbers, or any version numbers for that matter, and realize that they're there to facilitate automation, not to satisfy some sense of human aesthetics.

</comment><comment><USER10> If the asshole responsible for this mess can chime in for a moment ;)

I figured that it was worth a bit of a longer explanation (cross-posted from [https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e](https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e))

\---

Spurred by this thread, here's is a quick set of jotted-down thoughts about the state of "Semantic" Versioning, and why we should be fighting the good fight against it.

For a long time in the history of software, version numbers indicated the relative progress and change in a given piece of software. A major release (1.x.x) was _major_ , a minor release (x.1.x) was _minor_ , and a patch release was just a small patch. You could evaluate a given piece of software by name + version, and get a feeling for how far away version 2.0.1 was from version 2.8.0.

But Semantic Versioning (henceforth, SemVer), as specified at [http://semver.org/](http://semver.org/), changes this to prioritize a mechanistic understanding of a codebase over a human one. _Any_ "breaking" change to the software must be accompanied with a new major version number. It's alright for robots, but bad for us.

SemVer tries to compress a huge amount of information — the nature of the change, the percentage of users that will be affected by the change, the severity of the change (Is it easy to fix my code? Or do I have to rewrite everything?) — into a single number. And unsurprisingly, it's impossible for that single number to contain enough meaningful information.

If your package has a minor change in behavior that will "break" for 1% of your users, is that a breaking change? Does that change if the number of affected users is 10%? or 20? How about if instead, it's only a small number of users that will have to change their code, but the change for them will be difficult? — a common event with deprecated unpopular features. Semantic versioning treats all of these scenarios in the same way, even though in a perfect world the consumers of your codebase should be reacting to them in quite different ways.

Ultimately, breaking changes are no fun, and we should strive to avoid them when possible. To the extent that SemVer encourages us to avoid changing our public API, it's all for the better. But to the extent that SemVer encourages us to pretend like minor changes in behavior aren't happening all the time; and that it's safe to blindly update packages — it needs to be re-evaluated.

Some pieces of software are like icebergs: a small surface area that's visible, and a mountain of private code hidden beneath. For those types of packages, something like SemVer can be helpful. But much of the code on the web, and in repositories like npm, isn't code like that at all — there's a lot of surface area, and minor changes happen frequently.

Ultimately, SemVer is a false promise that appeals to many developers — the promise of pain-free, don't-have-to-think-about-it, updates to dependencies. But it simply isn't true. Node doesn't follow SemVer, Rails doesn't do it, Python doesn't do it, Ruby doesn't do it, jQuery doesn't (really) do it, even npm doesn't follow SemVer. There's a distinction that can be drawn here between large packages and tiny ones — but that only goes to show how inappropriate it is for a single number to "define" the compatibility of any large body of code. If you've ever had trouble reconciling your npm dependencies, then you _know_ that it's a false promise. If you've ever depended on a package that attempted to do SemVer, you've missed out on getting updates that probably would have been lovely to get, because of a minor change in behavior that almost certainly wouldn't have affected you.

If at this point you're hopping on one foot and saying — _wait a minute, Node is 0.x.x_ — SemVer allows pre-1.0 packages to change anything at any time! You're right! And you're also missing the forest for the trees! Keeping a system that's in heavy production use at pre-1.0 levels for many years is _effectively the same thing as not using SemVer in the first place_.

The responsible way to upgrade isn't to blindly pull in dependencies and assume that all is well just because a version number says so — the responsible way is to set aside five or ten minutes, every once in a while, to go through and update your dependencies, and make any minor changes that need to be made at that time. If an important security fix happens in a version that also contains a breaking change for your app — you still need to adjust your app to get the fix, right?

SemVer is woefully inadequate as a scheme that determines compatibility between two pieces of code — even a textual changelog is better. Perhaps a better automated compatibility scheme is possible. One based on matching type signatures against a public API, or comparing the runs of a project's public test suite — imagine a package manager that ran the test suite of the version you're currently using against the code of the version you'd like to upgrade to, and told you _exactly_ what wasn't going to work. But SemVer isn't that. SemVer is pretty close to the most reductive compatibility check you would be able to dream up if you tried.

If you pretend like SemVer is going to save you from ever having to deal with a breaking change — you're going to be disappointed. It's better to keep version numbers that reflect the real state and progress of a project, use descriptive changelogs to mark and annotate changes in behavior as they occur, avoid creating breaking changes in the first place whenever possible, and responsibly update your dependencies instead of blindly doing so.

Basically, __Romantic Versioning __, not Semantic Versioning.

All that said, okay, okay, fine — Underscore 1.7.0 can be Underscore 2.0.0. Uncle.

(typed in haste, excuse any grammar-os, will correct later)

<comment><USER11> I appreciate your thoughts as always. I'm sure this is frustrating for you because you have a bunch of users yelling at you to do something in a way you don't agree with, and it's not like they _pay_ you for the right to do that.

A couple comments:

> Node doesn't follow SemVer, Rails doesn't do it, Python doesn't do it, Ruby > doesn't do it, jQuery doesn't (really) do it

Node does (because it's <1.0.0 where semver's rules are different). Everything else you list is older than semver, so short of a time machine or a radical change to their long-established versioning policies, there's not much they can do.

> the responsible way is to set aside five or ten minutes, every once in a > while, to go through and update your dependencies, and make any minor > changes that need to be made at that time.

That works fine for your _immediate_ dependencies. The reason why I think things like semver are important is that the above doesn't work at all with transitive dependencies.

If my app uses foo which uses bar which uses baz and the maintainers of baz decide to make a breaking change in a minor version, I'm not in a happy place when that wolf in sheep's clothing appears in my dependency graph. I'll see that my app is broken, but unless I want to fork bar and maybe foo and start mucking around in code I've never touched before, my options are pretty limited.

I don't think semver is perfect, but I find it does make transitive and shared dependencies a lot more reliable to work with. I'm willing to sacrifice human- meaningful version numbers to get that.

<comment><USER12> > Node does (because it's <1.0.0 where semver's rules are different)

You might've missed the paragraph preëmptively responding to that (it was added in an edit).

SemVer says that you shouldn't be pre-1.0.0 if you're actively used in production anywhere. Node has been out for years. Treating the current versions of Node as pre-1.0.0 is a joke.

From the semver.org FAQ:

> How do I know when to release 1.0.0?

> If your software is being used in production, it should probably already be > 1.0.0. If you have a stable API on which users have come to depend, you > should be 1.0.0. If you're worrying a lot about backwards compatibility, you > should probably already be 1.0.0.

Node definitely applies.

<comment><USER13> There is no way an author / project can control when someone is going to use their software 'in production', I would certainly argue that condition is the weakest of indicators as to whether something is 1.0.0 or not.

Aside from that, the other 2 indicators definitely do not apply to Node (API is not stable, there is not a lot of worry about backwards compatibility as you'll see in the upcoming 0.12 release).

So no, Node is not '1.0.0' according to SemVer.

</comment></comment></comment></comment><comment><USER14> The blame for this falls squarely on NPM for replacing the default ~ (update patches) with ^ (update minor versions).

The only reason for having automatic package updates in the first place is to receive bug and security patches. There is little gain in receiving 'minor' updates if you are not changing your code, and any serious project will end up freezing the dependency tree anyway.

<comment><USER5> Is this ironic?

[https://github.com/npm/npm/releases/tag/v1.4.3](https://github.com/npm/npm/releases/tag/v1.4.3)

[look at the patch number...]

</comment></comment><comment><USER15> I'm a bit surprised no one has mentioned FerVer(Fear-Driven Versioning) yet, it was made in an effort to fix exactly this kind of problem. [1]

[1] [https://github.com/jonathanong/ferver](https://github.com/jonathanong/ferver)

</comment><comment><USER16> It's really not that hard.

If you have a lot of breaking changes, you probably shouldn't be at 1.x.x. If you need to deprecate something, add the extra features alongside and remove the deprecated features in the next major release. If you need to add something to code that is >= 1.x.x and you think it will need breaking changes, you should mark the feature as experimental in the documentation until it has stabilized. Semver works great for humans and robots if you put a smidgeon of planning and consideration into the process!

</comment><comment><USER17> Simple, add an optional human significant "ultra" version (better name suggestions welcome) to indicate a philosophical version upgrade consistent with how major versions have historically been used (as marketing communications).

E.g., 18.104.22.168 or 1.7.0 are equivalent.

[Cross posted from the other thread: [https://news.ycombinator.com/item?id=8244920](https://news.ycombinator.com/item?id=8244920)]

</comment><comment><USER18> Can someone outline who the people arguing against Jeremy Ashkenas are?

It would make a big difference if they were ordinary users, vs maintainers of other important libraries of pieces of software.

While everyone deserves their say, this issue seems somewhat subjective, and a package maintainer shouldn't have to pay undue attention to individual users who don't necessarily represent the whole community.

</comment><comment><USER19> This link ([http://www.jongleberry.com/semver-has-failed- us.html](http://www.jongleberry.com/semver-has-failed-us.html)) was also posted on HN a while ago.

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

</comment><comment><USER12> See also [https://github.com/jashkenas/underscore/issues/1684](https://github.com/jashkenas/underscore/issues/1684)

</comment><comment><USER20> It takes the same amount of effort to type "2.0.0" as it does "1.7.0" but the effects of this choice are obviously much larger. Why is it such a roadblock to not break everyone else's code?

<comment><USER21> It sounds like the maintainers reasoning is "pretty much every version is going to break something somewhere"

<comment><USER22> That is where I get lost. What is wrong with that?</comment></comment></comment>


Ask HN: What three books impacted your career the most? - <AUTHOR> A young version of yourself is about to start their career and you can give them three books, but only three books, what would they be? <comment><USER3> 1\. The Bible. It encourages me to live in a way that's also good for others, especially when I'm feeling selfish and cynical, and it teaches me how to interact with them in a healthy way (e.g. the book of Proverbs).

2\. The Elements of Style. I always enjoyed writing, but at first school taught me to write in a flowery, longwinded way. This was the book that cracked the code for me to good writing. It dispelled a lot of self-serving and ultimately self-defeating habits and paved the way to clean, helpful English. When I finally got into programming in my late twenties, I found that many of the same principles make good code.

3\. The Visual Display of Quantitative Information. This is like the Elements of Style but for graphs. Again, it encouraged me to cut through the hype and deliver the content as clearly and succinctly as possible --- to serve the reader, not stroke my ego.

</comment><comment><USER4> 1) Outliers by Malcolm Gladwell: I bought this book after it was referenced in one of Alex Ferguson's books. It's a fascinating tale of how people became to be successful by being the right person in the right environment at the right time, from how Bill Gates dominated the world of software, to how The Beatles became one of the best bands in the world. It's a great reminder that a mixture of hard work, the right environment, and dumb luck will help you do well.

2) C# in Depth by Jon Skeet: Buying and reading this book is what led me to continue down the deep rabbit hole of .NET development, and following the C# language from version 1 onwards via the book is a great way to appreciate the language, as well as use it. As someone that writes C# daily this is the main book I recommend to existing devs.

3) Introduction to Algorithms by CLRS: This is a bit of a cheat, because I've only glanced at various pages of this book. I have a degree in Computer Science, but my maths knowledge is lacking (to put it kindly), so despite my degree I have only a practical understanding of a lot of the algorithms talked about in the book. It's been my goal for years to build up my knowledge of maths to the point where I can read this book cover-to-cover and actually understand what's going on. I'm still not there, but hopefully one day I'll make it.

<comment><USER5> I can't agree more on #3. But there are few other books which take a less mathematical approach and I have found it quite useful.

<comment><USER4> I've picked up quite a few over the years, with my favourite being Algorithms by Sedgewick.

With that being said, I've tried to teach myself about the most important data structures and algorithms, but I find that I'm not "really" understanding them, and am purely just remembering the gist of what I need to know.

Perhaps it's imposter syndrome, but despite being a passable developer, there's a part of me that feels that I need to be able to read the CLRS book and actually understand what's going on, because until I can read that book I don't feel that I know the ins-and-outs of these algorithms.

</comment></comment></comment><comment><USER6> 1) _Hackers and Painters_ , by Paul Graham—This book had a huge influence on me and is why I left a successful and growing low tech business in Asia to move to California and become a software engineer.

2) _Zero to One_ , by Peter Thiel—Zero to one opened my eyes to several angles of business that I hadn't been thinking about. It made me think much harder about making long-term plans towards a concrete goal, even if changes must be made along the way. It also clarified my thoughts about the nature of competition and non-conformity. Courage is in even shorter supply than genius.

3\. _The Hero with a Thousand Faces_ , by Joseph Campbell—While it's not a business book, this book is a deep look at mythology and psychology. I find it helpful both for understanding people and for understanding myself.

<comment><USER7> Same top two, 3) Softwar: Larry Ellison and Oracle by Matthew Symonds

</comment></comment><comment><USER8> 1\. Godel, Escher, Bach -- Because it sparked my interest and got me started down the path.

2\. The Pragmatic Programmer -- a classic. Reminds me that I need to re-read it.

3\. Effective Oracle by Design, by Tom Kyte -- Not that I use Oracle any more, thankfully, but really provided a lot of insight about how databases function and how it pays to deeply understand their internals when writing webapps.

<comment><USER9> +1 on the Pragmatic Programmer.

For anyone that is ready to stop consuming themselves with all things esoteric and start writing generally good code by default.

If more devs followed the relatively simple patterns and practices in this book the phrase "legacy code" might not be a curse-word.

</comment></comment><comment><USER10> Sartre's "Nausea", which demonstrates the pointless nothingness of life, so one should not get too stressed out at work because Frank doesn't like your indentation style but that's how everyone at university does it ...

</comment><comment><USER11> Practical skills are easily acquired. Personal skills and greater self- awareness are what really fast-track you.

1) Scott Adams 'How to fail at almost everything' for life strategy.

2) Robert Glover's 'No more Mr Nice Guy' for assertiveness and being your authentic self no matter what.

3) As cliche as it is, 'The Power of Now' is a great source to return to in times of personal and professional woes.

Good luck and Godspeed in your career(s).

<comment><USER12> I've not read any of those, but the title of #2 struck a chord.

I remember years ago complaining to someone that the manager of a project whose code I needed kept refusing to fix the showstopping bugs in it. His answer was "go over his head to _his_ manager. No more Mr Nice Guy."

I thought it over and he was right: I'd tried being reasonable for as long as I could and this guy was preventing me from doing my job properly. I spoke to his manager (who I had a great relationship with BTW) and the problem was fixed literally within minutes.

Since then I've taken that approach to heart: either work with me or get the hell out of my way because I won't be held back.

<comment><USER13> As a christian, I found _parts_ of No More Mr. Nice Guy a bit less worthy, but I can highly recommend the book as a whole if you find yourself unbalanced.

The author isn't recommending anybody to be a jerk, but his admonitions to being more forthright, up-front, and a bit less scheming will help people find balance. And in consequence actually treating people with respect rather than project a somewhat false "nice-guy" facade.

</comment></comment></comment><comment><USER14> First part of the question (actual influences):

1) Philip and Alex's Guide to Web Publishing (not strictly a book). [http://philip.greenspun.com/panda/](http://philip.greenspun.com/panda/)

2) The "Dragon Book" [https://en.wikipedia.org/wiki/Principles_of_Compiler_Design](https://en.wikipedia.org/wiki/Principles_of_Compiler_Design)

3) Computer Architecture: A Quantitative Approach

Second part (at hindsight):

1) [https://en.wikipedia.org/wiki/Rich_Dad_Poor_Dad](https://en.wikipedia.org/wiki/Rich_Dad_Poor_Dad) (cheesy, but useful)

2) [http://toddkashdan.com/upside.php](http://toddkashdan.com/upside.php)

3) [https://www.schranner.com/de/news/2012/04/16/-verhandeln- im-...](https://www.schranner.com/de/news/2012/04/16/-verhandeln-im- grenzbereich-und-teure-fehler-jetzt-auch-im-apple-ibook-store) \- German book about negotiations written by an experienced hostage negotiator.

</comment><comment><USER15> 1\. "The Adventures of Sherlock Holmes" by Arthur Conan Doyle.

This may sound like an odd one, but years ago, I almost never took the time to read. My girlfriend, who knew that I loved Sherlock Holmes books when I was younger, convinced me to try this book as an audiobook while I did my ~40 minute commute to work. I was skeptical, but within days, I was hooked. It made my work commute much more interesting (a British person was reading me Sherlock Holmes!); then I started listening to audiobooks during all my driving (instead of wasting time, I can learn!); then I got an iPod, put audiobooks on that, and started listening to them during all sorts of odd chores (e.g. cleaning, walking, biking); after that, I was so hooked on books, that I started making time to read them too. This had a profoundly transformative effect on my career.

2\. "The Lean Startup" by Eric Ries.

I got a copy of this book when I went to a talk by Eric Ries. Eric seemed like a humble, down-to-earth person and helped dispel the notion that to be a successful entrepreneur, you need to be a prescient, superhero, god-like visionary. Instead, what you need to do is to treat your startup and product ideas as hypotheses and test them, as quickly and cheaply as you can (i.e. lean development, MVPs, etc). This fit very well with what I had seen in the real world and with how I thought about problem solving as a software engineer, and gave me a lot of confidence to try out many of my ideas. Since then, I've used these ideas to start a company ([http://www.gruntwork.io/](http://www.gruntwork.io/)) and written quite a bit on what I learned, including an article on The Macro about MVPs ([http://themacro.com/articles/2016/01/minimum-viable- product-...](http://themacro.com/articles/2016/01/minimum-viable-product- process/)).

3\. "On Writing Well" by William Zinsser.

If Conan Doyle taught me about the fun of reading, then William Zinsser taught me about the fun of writing. If you want to learn how to write, what it's like to write, or why you should write ("Writing is not a special language owned by the English teacher. Writing is thinking on paper."), it's hard to find a better guide. This book significantly improved my writing skills and even gave me the confidence to write a book ([http://www.hello- startup.net/](http://www.hello-startup.net/)).

<comment><USER3> > "On Writing Well"

Love that book

</comment></comment><comment><AUTHOR> I'll add my current three,

        1) "How to Win Friends and Influence People"
        2) "The War of Art"
        3) "The Pragmatic Programmer"

<comment><USER16> Can you explain what you liked about The War of Art? I read it because I have seen it mentioned on this site many times, but I did not enjoy it at all. I found that the first two sections contained very little useful information, and the third got somewhat silly when it started evoking angels and muses. I could see it being a motivational read for some?

I find it strange that it's mentioned in the same context as your #1 and #3, which I think are absolutely essential.

</comment></comment><comment><USER17> As a reader of books, one of the good things about growing older is that the books the younger version of myself read are books that this older version of myself hasn't and there is great pleasure in rereading the books the younger version of myself read as the older person I am.

And that makes this exercise impossible for me. The books I would tell the younger version of myself to read wouldn't resonate the same way (or not at all) with that other person I used to be. Picking books that might have appealed to the younger version of myself accurately would mean picking the books I actually read -- e.g. _The Fifth Discipline_ \-- and not books that the younger version of myself tried to read but couldn't but that I read and recommend today: e.g. _TAoCP_.

Part of the complexity is that the world in which I read books today is radically different from that of my younger self. Today I can get a MIX interpreter from the internet [1]...there's even help on StackOverflow. My younger self couldn't because even in the time when there was an internet bandwidth was low and Google didn't exist.

Like I said it's great to pick up a good book and realize it is better than I remember when I remember it being really good, but it's hard to see how it could have been better for my younger self.

1\. _Neuromancer_

2\. _Blood Meridian_

3\. _A Pattern Language_

[1]:[https://apps.ubuntu.com/cat/applications/precise/mixal/](https://apps.ubuntu.com/cat/applications/precise/mixal/)

</comment><comment><USER18> 1\. Assembly Language and Computer Architecture Using C++ and Java , Course Technology, 2004 by Anthony J. Dos Reis

2\. Compiler Construction Using Java, JavaCC, and Yacc, IEEE/Wiley, 2012 by Anthony J. Dos Reis

3\. An Introduction to Functional Programming Through Lambda Calculus by Greg Michaelson

I'm lazy now so just look on my previous comment:

[0] - [https://news.ycombinator.com/item?id=12099943](https://news.ycombinator.com/item?id=12099943)

</comment><comment><USER19> The C Programming Language, Kernighan and Ritchie, for its simple elegance.

The Elements of Style, Strunk & White. On clear writing.

Hitchhiker's Guide to the Galaxy (series), Douglas Adams. So you don't take yourself too seriously.

</comment><comment><USER20> Thinking Fast and Slow, Daniel Kahneman

How I raised myself from failure to success in selling, Frank Bettger

Thinking in Systems: A Primer, Daniela Meadows

Most important thing is to get up and start doing stuff, understand how you personally f$$k things up and reap benifits of compound interest in personal development. I think these three bookshave a lot of information that is usable in any career or path one might choose.

<comment><USER21> Donella* Meadows is the author of #3

Great primer for folks unfamiliar with systems engineering.

</comment></comment><comment><USER22> If I were to go back and be young - I would dedicate myself to read plenty of books and probably find three genres which would appeal. A measure of a good book is how likely will it lead you to read another great book or how likely is that it changes the perception of another book/knowledge or makes you question-argue fundamental value systems. Wish there was kind of backlink algorithm to measure a book like that. I've found below genre-and-author that appeal more over time and you keep going back to them.

> Tech : C - Kernighan & Ritchie (may be a good python/nodejs book today).

> About tech people : Made in Japan - The Google Speaks - The Everything store > - Hatching Twitter - Steve Jobs - Zero to One - Hard things about hard > things.

> About non-tech people : Founding fathers - Obama - Einstein - Darwin - > Feyman - Teresa - Montessori - Gandhi - Mandela - Che Guevera - Churchill.

> Last but important: Tolstoy - Plato - Enlightenment-Era-Books - > Religions(all) - Military fitness.

</comment><comment><USER23> 1\. "Meditations" – Marcus Aurelius

2\. "The Practicing Mind" – Thomas Sterner

3\. "Better: A Surgeon's Notes on Performance" – Atul Gawande (I'm not a surgeon; the principles herein are universal)

(honorable mention: "How to Win Friends and Influence People" – Dale Carnegie; various biographies by Caro and Chernow)

</comment><comment><USER24> 1\. Head First Design Patterns - Didn't learn patterns in school. This book made a lot of difference in communication with more experienced programmers.

2\. Pragmatic Programmer - A classic, learned many practical tips for day to day programming job.

3\. Founders at Work - Motivated me to work on my side projects and be constantly learning.

<comment><USER25> Head First Design Patterns is awesome. I read a couple other Design Pattern books, but didn't really get it. I didn't want to buy a "Head First" book because it looked kind of silly, but this book has finally opened my eyes to what Design Patterns are about.

</comment></comment><comment><USER26> Thinking, Fast and Slow - Daniel Kahneman. Learn why we're fools by nature.

Incerto - Nassim Nicholas Taleb (4 volumes, with The Black Swan as my favourite). Learn how not to be a fool, or at least, minimize its impacts.

The Startup Owner's Manual - Steve Blank. Learn how to find your way through the market.

</comment><comment><USER27> Code complete was a great early read for someone who already knew the basics of programming

L'etranger Albert Camus, for the same reasons as jjgreen

A Herbert Shilt book on C programming but could have been K&R instead, was part of the process from moving from simple basic coding to software development

</comment><comment><USER28> "Thinking Forth" by Leo Brodie --> [http://thinking- forth.sourceforge.net/](http://thinking-forth.sourceforge.net/)

"How Buildings Learn: What Happens After They're Built" by Stewart Brand --> [http://www.openculture.com/2015/07/watch-stewart- brands-6-pa...](http://www.openculture.com/2015/07/watch-stewart- brands-6-part-series-how-buildings-learn-with-music-by-brian-eno.html)

"Programmer's Guide to the 1802" by Tom Swan --> [http://www.tomswan.com/store/](http://www.tomswan.com/store/)

</comment><comment><USER29> 1\. "Zen and the art of motorcycle maintenance" by Robert Pirsig

2\. "The art of war" by Sun Tzu

3\. "Meditations" by Marcus Aurelius

</comment><comment><USER30> 1) "how life imitates chess" Garry Kasparov

2) "how life imitates chess" Garry Kasparov

3) "how life imitates chess" Garry Kasparov

Highly recommended, very good read and smart book. I would call it the modern version of The Art of War.

<comment><USER31> Such a coincidence that they have the same title and author name.

</comment></comment><comment><USER32> 1\. "The Age of Spiritual Machines" (2000) by Ray Kurzweil. This futurist book sparked my imagination at a young age as to what was possible with technology. Several of its predictions that have come true today.

2\. "Creativity Inc." (2014) by Ed Catmull. Fascinating stories and lessons from the man who ran Pixar, the animated film company with 11 straight number 1's at the box office.

3\. "Outliers" by Malcolm Gladwell. Along with talent and hard work, being well-positioned is a big part of success. Put in 10,000 hours to be great at anything.

</comment><comment><USER33> 1\. "The Seven Habits of Highly Effective People" by Stephen Covey. Taught me how to be more productive and simplify thinking about productivity. One of the books I re-read every year.

2\. "The Bible" \- I am not too religious, but I am a spiritual person. I find the new testament to be a good blueprint on how to live a righteous life.

3\. "The Pragmatic Programmer: from journeyman to master" \- such a timeless classic. Just get it...

</comment><comment><USER34> 1\. Peopleware 2\. The C Programming Language 3\. Design Patterns: Elements of Reusable Object-Oriented Software

Honorable mention: Compiler Design in C

</comment><comment><USER35> 1\. Start with why, Simon Sinek - to get my younger self to figure out why I am doing what I am doing

2\. Drive, the surprising truth..., Daniel Pink - to understand happiness and motivation

3\. Crucial Conversations, to learn how to talk and listen and talk to people without ruining the conversation and the possibilities from it

</comment><comment><USER36> Career not life, so:

K&R C (Draft ANSI Edition) - A small book that shows how you should write. Many of the examples are not really good code anymore, but it traveled and inspired.

Perl Little Black Book - I needed to learn Perl and it was packed. Much like many of the ORA pocket references, except with a lot more examples. My copy is in rough shape with flags, notes, and highlights.

I will have to dig it out of a box, but I had a system process and design book from a college class that I used extensively in my first decade of work. I think I internalized it all. I put the book in a crate with my K&R C book waiting for a good shelf to put it on when I get somewhere a little more permanent.

</comment><comment><USER37> The headline and the body are posing two different questions. Regarding books that impacted my career in software. The top three are:

1) K&R C

2) Zen of Graphics Programming

3) C++ Programming Language, 2E

I wouldn't recommend any of these to a young version of myself today.

</comment><comment><USER38> 1\. Think and grow rich: Thought me about goal setting, opened my eyes to the fact that a man can rise from his humble beginnings to any height he want's to attain if he is willing to work for it.

2\. PHP for dummies: My first exposure to the world of programming, since then I've never looked back.

3\. Rich Dad, Poor Dad: Changed my thinking about finance, I don't know how I would have handled my finances if I hadn't come across this book as a teenager, I feel so lucky to have read this book. I would have been stuck in society's harmful way of handling finance.

</comment><comment><USER39> I'm pretty early in my career. There's just one book on my list now (and that's simply because I haven't made time to read others): The Clean Coder, by Robert Martin

</comment><comment><USER40> "The Goal" \- Started my interest in Lean principles, along with how to apply them to programming - imagining my programs as little data "factories", that need to be made efficient and efficiently.

"How I Found Freedom in an Unfree World" \- Taught me I don't need to follow the standard path that "everyone else does", and to focus on how I can actively change my world - instead of waiting for someone else to to change it for me.

"Code Complete" \- Get it. Read it. Live it.

</comment><comment><USER41> "Cracking the Coding Interview" (probably wouldn't even have a career without this book)

"The Little Schemer"

"Stories of Cats and the Lives They Touch" by Peggy Schaefer

<comment><USER42> I strongly recommend The Little Schemer to any programmer.

</comment></comment><comment><USER43> How to Win Friends and Influence People by Dale Carnegie.

All of your working life is built on relationships, even if you code all day.

</comment><comment><USER44> There were different book that impacted different stages of my career:

As a programmer :

1\. The C++ Programming Language by Bjarne Stroustrup.

2\. Operating System Concepts by Silberschatz

3\. Compilers by Aho

As an agile software developer:

1\. eXtreme Programming by Kent Beck

2\. Pragmatic Programmer by Hunt and Thomas

3\. Continuous Delivery by Jez Humble

As an architect:

1\. Domain Driven Design by Evans

2\. Pattern-Oriented Software Architecture by Buschmann

3\. Envisioning Information by Edward Tufte

As a CEO:

1\. Good To Great by Collins

2\. Lean Startup by Eric Ries

3\. Beyond Budgeting by Pfläging

</comment><comment><USER45> 1\. "The Lean Startup" by Eric Ries

2\. "Insanely Simple" by Ken Segall

3\. "How to Measure Anything" by Douglas W. Hubbard

</comment><comment><USER46> Carol Dweck's "Growth mindset". This book changed my view of diligence and intelligence.

</comment><comment><USER47> \- The Pragmatic Programmer (Hunt/Thomas)

\- Computer Architecture - A Quantitative Approach (Hennessy/Patterson)

\- Expert C Programming - Deep C Secrets (van der Linden)

I woud call the Pragmatic Programmer though by far the most influential.

<comment><USER48> Interesting that this book is mentioned in this thread several times. I didn't find this book bringing almost any value to me. What it did was giving names (e.g. orthogonality) that I didn't know before to the common programming concepts that all developers with some practical experience should be aware of anyway as a common sense. But that might just be due to a different approach to programming.

I find the books such as Andrew Tanenbaum's "Computer Networks" which are bringing historical perspective as well as a lot of technical information without going into the tiny details the best balance of useful and interesting.

Therefore "Computer Architecture - A Quantitative Approach" is much better for me in that aspect and the C programming should be really interesting too, although I haven't read it.

</comment></comment><comment><USER49> 1.The Trouble with Lawyers - an early introduction to conflicts of interest

2.One Up On Wall Street - insiders view of the markets and other lessons

3.Consilence - how to distinguish real things from unreal things

</comment><comment><USER50> \- The Peter Principle: Why Things Always Go Wrong by Lawrence J. Peter & Raymond Hull

\- The Upside of Irrationality by Dan Ariely

\- Screw It, Let's Do It: Lessons In Life by Sir Richard Branson

</comment><comment><USER51> The Pragmatic Programmer, Dave Thomas, Andy Hunt

Fooled by Randomness, Taleb

Linchpin, Seth Godin

</comment><comment><USER52> 1.How to fail at almost everything and still win big- Scott adams 2.The Surrender Experiment - Michael Singer 3.Choose Yourself - Jamel Altucher

</comment><comment><USER53> 1\. Beating the Street - Peter Lynch 2\. More Money than God - <USER2> Mallaby 3\. Dark Pools - Scott Patterson

</comment><comment><USER54> 1) The Art of Unix Programming 2) TCP/IP Illustrated 3) 97 Things Every Programmer Should Know

</comment><comment><USER55> 1\. Ego Is the Enemy - Ryan Holiday

2\. sidebar from /r/theredpill

3\. The Millionaire Fastlane: Crack the Code to Wealth and Live Rich for a Lifetime

Book number 3 has probably the most 'click baity' and the most douchey title of all times. It sounds like one of those self help books or one of those get rich fast schemas but in fact, it's an eye opener and it encourages hard work.

<comment><USER56> Is #2 a joke? I sincerely hope it is. Such a hateful ideology has no place on Hacker News

<comment><USER57> Pretty sad this got flagged. Honestly, I would flag the Bible before it. I think I understand your reasoning. While I don't agree with it, it's no worse than Ayn Rand or Timothy Ferris.

<comment><USER17> I don't think the books were the cause.

</comment></comment></comment></comment><comment><USER58> "The Defining Decade: Why Your Twenties Matter" by Meg Jay

<comment><USER55> Is this going to make me sad if I read it by the age of 32 ?

<comment><USER13> Perhaps not. I'm 42 and I'm _tend_ to think of my station in life as just being delayed by 15 years - I had to get over a rather crappy childhood and a protracted adolescence.

(That said, I'd admonish anyone your age that if you don't have children, have them now rather than a series of compensating house-pets for the rest of your life)

<comment><USER55> > (That said, I'd admonish anyone your age that if you don't have children, > have them now rather than a series of compensating house-pets for the rest > of your life)

I should give up my dreams in order to have kids ?

Two years ago, I had an idea ( that failed but that's not the point here ), I wanted to finish it so I simply walked into the office and quit.

I worked 6 months on my project, I didn't care about someone else, just me and my project.

I value your opinion and if you think that you should have kids, do it but for me, right now it would be like a prison.

<comment><USER13> Note: I'm not necessarily wise.

Having children don't preclude following personal dreams - for my own situation - children enhanced my ability(and necessity) to discern if any potential dream was plausible, actionable, and worth the extra effort.

For example, I've given up trying to become a billionaire - my financial security is fine, so it would be regrettable to trade away going hiking with my family for extra money.

And as a practical matter, children are only horribly disruptive when very small - and they're quite fascinating as a source of entertainment in themselves.

But... here's the problem... biologically, female humans seem to be designed to have children easily up until about their mid-thirties (apparently longer if the specimen is fit and active.)

<comment><USER55> I like your perspective.

Because this:

> And as a practical matter, children are only horribly disruptive when very > small - and they're quite fascinating as a source of entertainment in > themselves.

Is actually very insightful.

> But... here's the problem... biologically, female humans seem to be designed > to have children easily up until about their mid-thirties (apparently longer > if the specimen is fit and active.)

No one told us that we have to choose a female of our own age. That's societies attempt to brainwash us. While it looks quite disgusting when people are 20-30 years apart, 10 years is totally ok.

</comment></comment></comment></comment></comment></comment><comment><USER59> "The Art of Learning" by Josh Waitzkin

<comment><USER60> I didn't realise he wrote a book. His chess videos in Chessmaster made me a much better player, I'll definitely have a look at the book.

</comment></comment><comment><USER61> 1) Shogun

2) Noble House

3) Excel by Que Publishing

</comment><comment><USER62> Probably the Dale Carnegie book, as dumb as that sounds.</comment>


Ask HN: How would you design Instagram? - <AUTHOR> I've gotten this problem _twice_ now from Trendy SV Companies and I've come up short each time. I'm clearly missing something in my explanation. If you give this problem, could you walk through the solution please?<p>Cheers! <comment><USER2> Can you talk a little more about the types of roles you're interviewing for and what your typical answer looks like? I think that would be useful to provide more context for any answer.

<comment><AUTHOR> Sure thing. I'm interviewing for "senior software engineering" roles: full- stack, approximately 3-5 years out of school.

To clarify, they specifically ask about the Instagram feed.

Basic answer goes like this: v0: Webserver handling requests talking to a relational DB. Return feed via ORDER BY created_at DESC; v1: introduce CDNs to host image files closer to the client. v2: pre-compute user's feeds and store them in a NoSQL table.

Where I struggle: * Solving the "push" vs "pull" aspect. v2 doesn't work well for influencers with huge follower counts. How to handle this case? I suggested a blended approach but didn't have many ideas on how to knit them together. * Would you still pre-compute the feeds even if people haven't logged in for a long period of time? I said we could bucket users into different categories of usage via an offline job and re-fresh their feeds on different cadences and store them in different levels of caching.

Curious to hear how I can add more detail and extend my solution!

</comment></comment><comment><USER3> Well that's a flawed question, as no one ever _designed_ instagram, it evolved through iteration to its current state.

If you tried to clone instagram now, it would take years to replicate every feature (for a single dev).

A better answer is to say you would design instagram the way they originally did.... Start with a simple photo sharing platform and add features based on user feedback and demand.

That way you're solving problems people are having, not copying a solution that already exists.</comment>


Clojure Protocols can extend final Java classes (like java.lang.String) - <AUTHOR> http://clojure.org/protocols

<comment><USER2> Reminds me of jwz's Java doc on the topic of final variables, and how the access is restricted by compiler convention, not in the JVM:

        System.in, out and err (the stdio streams) are all final
        variables. They didn't used to be, but some clever applet-writer
        realized that you could change them and start intercepting all output
        and do all sorts of nasty stuff. So, the whip-smart folks at Sun went
        and made them final. But hey! Sometimes it's okay to change them! So,
        they also added System.setIn, setOut, and setErr methods to change
        them!

        ``Change a final variable?!'' I hear you cry. Yep. They sneak in
        through native code and change finals now. You might think it'd give
        'em pause to think and realize that other people might also want to
        have public read-only yet privately writable variables, but no.

        Oh, but it gets even better: it turns out they didn't really have to
        sneak in through native code anyway, at least as far as the JVM is
        concerned, since the JVM treats final variables as always writable to
        the class they're defined in! There's no special case for
        constructors: they're just always writable. The javac compiler, on the
        other hand, pretends that they're only assignable once, either in
        static init code for static finals or once per constructor for
        instance variables. It also will optimize access to finals, despite
        the fact that it's actually unsafe to do so.

<comment><USER3> > some clever applet-writer realized that you could change them and start > intercepting all output and do all sorts of nasty stuff.

Can someone explain how this worked? What does he mean by "intercepting all output"?

<comment><USER4> Replace System.out with an object that responds to all of the same methods, but which does something clever with them. For instance one that adds timestamps on output, logs stuff somewhere, filters, etc.

This is a very powerful trick. However the downside is that it is in the category of things where only one person gets to be clever. Because the second person to replace that object breaks the first. So they decided to discourage that.

</comment></comment></comment><comment><AUTHOR> As simple as this:

      (defprotocol Foo
        (bar-ify [this]))

      (extend-type java.lang.String
        Foo
        (bar-ify [this] (.concat this "Bar")))

      (bar-ify "Hello world!")

Everything can be redefined interactively at the REPL. Also due to Rich Hickey's mad skills you get pretty much Java method dispatch performance.

EDIT: There is a gross misunderstanding about how this works. The following is invalid and will throw an exception, please take the time to understand this:

      user> (ns baz)
      baz> (bar-ify "foo")

Your changes will not affect use of java.lang.String in other libs.

<comment><USER5> I'd like to clarify that Protocols just generate a bunch of functions and a Protocol object (and an interface, but that's an implementation/interop detail). The functions are the interesting things in most cases. However, they're also namespaced like everything else. You can do the following though:

      user> (defprotocol Foo (describe [object]))
      user> (extend-type java.lang.String
              Foo
              (describe [string] "a String"))
      (ns bar)
      bar> (user/describe "String") -> "a String"
      bar> (extend-type java.lang.Object
             user/Foo
             (describe [obj] "an Object"))
      bar> (in-ns 'user)
      user> (describe 3) -> "an Object"
      user> (describe "Hello") -> "a String"

So there is potential for two libraries extending the same things and causing a conflict if the semantics differ, but I'm not too concerned about that. It would be rather rude to extend someone else's protocol to cover someone else's java class without documenting that you do so.

</comment></comment><comment><USER6> Why's this worth noting? There's no reason you shouldn't be able to extend a type with methods to support a new interface, no matter what that type's author intended. It's not in any sense "dangerous" to existing APIs, as changing final variables could potentially be. It seems like completely natural behavior.

<comment><USER7> _It's not in any sense "dangerous" to existing APIs_

If your job is to deliver and maintain such an API, then by allowing subclassing you have a larger contract you have to maintain when you want to make changes to the underlying class: rather than just the public interface, you also need to worry about the protected interface. If your API is new, you may want to shepherd your users (by marking a class as final) to favor composition over inheritance to maximize your ability to evolve the implementation in ways that don't break.

<comment><USER8> _by allowing subclassing you have a larger contract you have to maintain when you want to make changes to the underlying class: rather than just the public interface, you also need to worry about the protected interface._

In other words, if you allow subclassing, then you also have to worry about the interface that you have explicitly marked visible to subclasses.

Normally a non-problem, by definition.

 _final_ is useful when sealing a class that inherits from a parent class with a protected interface, but even if "final" is reduced to an annotation (or even a comment), its presence explicitly limits your end of the API contract.

<comment><AUTHOR> _There is no subclassing going on_. Take the time to actually read the documentation provided by the link.

<comment><USER8> The italicized portion at the top of my comment was a quote from the parent comment.

</comment></comment></comment></comment></comment><comment><USER9> Does is actually extend the class or simply wrap it with a decorator? I think Groovy takes this approach but I could be wrong.

<comment><USER5> It does neither. The dispatch logic is on the protocol side, which can be modified. When a class is extended, the protocol function is changed to have an extra instance check. (I don't understand the details in full, though. You'll need to ask Rich Hickey)

AFAIK there is also some kind of caching involved to improve performance.</comment></comment>


Free Bing API completely Dead - <AUTHOR> https://datamarket.azure.com/dataset/5BA839F1-12CE-4CCE-BF57-A49D98D29A44

<comment><USER2> If by "completely" you mean "not at all" then yes.

First 5,000 requests are still free, and the prices are very inexpensive at the low-end, and I'll bet at the high-end you are either generating revenue and/or could negotiate with them.

</comment><comment><USER3> The web search API remains free. Additionally, the other API features are free up to 5,000 transactions per month (images, maps, retail search, etc.)

I wouldn't say it's completely dead.

</comment><comment><USER4> This should not have been unexpected, given Microsoft's investment in Bing vs the cost of keeping a web index fresh and humming, it was inevitable. On the plus side, unlike other services, if you built your app on top of it you can pay for it and your app can continue running. This is, I expect, preferable to having the API be simply discontinued.</comment>


Love, Virtually: Why it's so easy to sell (sucker) relationships online - <AUTHOR> http://www.nytimes.com/2009/07/12/magazine/12FOB-medium-t.html?_r=1&ref=technology&pagewanted=print

<comment><USER2> Summary: Back in my day, we had to walk up hill _both ways, in the snow_ to have an affair.

<comment><USER3> Although a short witty and borderline un-HN comment, you managed to make me laugh _and_ save me the time of reading the article. I'm convinced that this is the correct way to do humor on HN :-)

</comment></comment><comment><USER4> The medium is the lover

<comment><USER5> Massage from the Medium

<comment><USER4> A Happy Ending is so close, yet so far

</comment></comment></comment><comment><USER6> This could have been really funny. It wasn't.</comment>