Fear, trust and JavaScript: When types and functional programming fail - <AUTHOR> https://www.reaktor.com/blog/fear-trust-and-javascript/ <comment><USER4> The author talks about Immutable.js, but doesn't mention Records, which have been a real godsend in my application. I use Immutable.Record with types [1] (using Flow), and I feel very confident with this setup. You are forced to set default values for every key, and the code will crash if you try to set a key that hasn't been defined.

It's really great to have typed Records (often nested), and I expose the getters as regular properties so that I don't have to call "get()" all the time. I agree that it's not perfect, but it's miles ahead of anything I've worked with in the past (at least in terms of JavaScript.)

JSON schemas are awesome, and I like the idea of validating types at runtime on the front-end. I already have a JSON schema that defines my API (I use Swagger), so I could even go one step further and auto-generate my typed Records directly from the schema. I'll get immediate feedback about any type errors in my JS codebase as soon as I make changes to the API. I generate my Swagger API specification automatically from some RSpec tests (using rswag [2]), and I also run Flow during CI, so this would result in a broken build. I could also make this work with the data I'm inlining in the HTML to hydrate the Redux store.

Random aside: I also have a one set of data that just gets dumped into a jsonb database column, so the schema for this specific data is only being defined by the front-end code. In my backend I'm always careful to provide a default value, but it's not really critical data. Anyway, I just realized that I should be defining this jsonb column as an actual model, but instead of ActiveRecord, I could use ActiveModel and a plain Ruby class. That's a neat idea. It would give me a schema and validations on the backend, while still having the flexibility and performance of storing everything in a single json column.

[1] [https://gist.github.com/glenjamin/75a96b45f4bb5c6ac221815d28...](https://gist.github.com/glenjamin/75a96b45f4bb5c6ac221815d28c548dd)

[2] [https://github.com/domaindrivendev/rswag](https://github.com/domaindrivendev/rswag)

<comment><USER5> With Bucklescript/Reason you get typesafety, immutability, performance and small codesize:

>Now we compare the runtime performance:

       BuckleScript Immutable Map: 1186ms
       Facebook Immutable Map: 3415ms

We also compare code Size:

        BuckleScript (Prod mode): 899 Bytes
        Facebook Immutable: 55.3K Bytes

source:

[https://github.com/BuckleScript/bucklescript/wiki/Why- buckle...](https://github.com/BuckleScript/bucklescript/wiki/Why-bucklescript- matters-for-Javascript-platform)

<comment><USER6> Does BuckleScript do any runtime type checking? If not, you have the same problem the moment you call out into any pure JS library - your type annotations say what you expect, but JS code can merrily give you something else.

<comment><USER7> That just means the type annotations are incorrect, and how would runtime type checking solve that?

<comment><USER6> It wouldn't solve that, but it would prevent the code from running with data that is incorrect according to type annotations. Think of it as a runtime assert that is automatically generated from the compile-time type annotation.

(Unfortunately, the JS runtime object model does not allow for such runtime type checks to be performed with reasonable performance.)

</comment></comment></comment></comment></comment><comment><USER8> > in various cases the types are wrong and the compiler doesn't care

It's disturbing how often I encounter this in TypeScript. Or its inverse: the types are correct and the compiler is wrong. Or a third common problem: the types for a library are incorrect. The unsoundness of TypeScript is not merely theoretical. The compiler is frequently just wrong. For that reason, I am mystified by the amount of enthusiasm for TypeScript that I encounter online.

<comment><USER9> 100% agree with this. If you're using redux the boilerplate of Typescript is huge. To do that all that work and still have the compiler miss problems at the state level deemed Typescript pointless to me.

<comment><USER10> Not sure which specific issues you encountered, but I had issues with defining actions and using their types in a union to the reducer.

There is a nice little library [1] that fixes this issue.

So a general redux setup looks as follows:

        const FETCH_USERS_BEGIN = "@@FOO/FETCH_USERS_BEGIN"
        const FETCH_USERS_SUCCESS = "@@FOO/FETCH_USERS_SUCCESS"
        const FETCH_USERS_ERROR = "@@FOO/FETCH_USERS_ERROR"

        const fetchUsersBegin = () => action(FETCH_USERS_BEGIN)
        const fetchUsersSuccess = (users: IUser[]) => action(FETCH_USERS_SUCCESS, users)
        const fetchUsersError = () => action(FETCH_USERS_ERROR)

        type IActions =
          | ReturnType<typeof fetchUsersBegin>
          | ReturnType<typeof fetchUsersSuccess>
          | ReturnType<typeof fetchUsersError>

        interface IUser {
          id: number
          name: string
        }

        interface IState {
          readonly isLoading: boolean
          readonly isErrorLoading: boolean
          readonly allIds: number[]
          readonly byId: {
            readonly [key: number]: IUser
          }
        }

        const defaultState = {
          isLoading: false,
          isErrorLoading: false,
          allIds: [],
          byId: {}
        }

        const reducer = (state: IState = defaultState, action: IActions) => {
          // narrowing on types
          switch (action.type) {
            case FETCH_USERS_BEGIN:
              return { ...state, isLoading: true, isErrorLoading: false }
            case FETCH_USERS_SUCCESS:
              return {
                ...state,
                byId: action.payload.reduce(
                  (acc, u) => ({ ...acc, [u.id]: u }),
                  {}
                ),
                allIds: action.payload.map(u => u.id),
                isLoading: false,
                isErrorLoading: false
              }
            case FETCH_USERS_ERROR:
              return {
                ...state,
                isLoading: false,
                isErrorLoading: true
              }
            default:
              return state
          }
        }

[1]: [https://github.com/piotrwitek/typesafe-actions#1-classic- js-...](https://github.com/piotrwitek/typesafe-actions#1-classic-js-style- with-constants-ftw)

<comment><USER11> I've found myself preferring type guards for checking action type, since it avoids you having to have keep one big `Actions` union around that takes X amount of lines and really doesn't serve any other purpose.

</comment></comment></comment></comment><comment><USER12> This article is just a recapitulation of the old pure functional programming vs. imperative programming argument but wrapped up in new packaging. Most of these issues, such as needing to validate types at codebase boundaries, functions that have side effects, and unsound static type systems, could just as easily be leveled at most imperative languages (C++, Java).

So yeah, go use a proper functional language (many of which compile to JS!). Complaining that an imperative language isn't a soundly-typed functional language is tautologically true I guess, but who cares?

<comment><USER13> It's not really, though. Because even pure FP folks read this article and say, "This is just nonsense and ill-considered propaganda."

For example, the idea that you can't trust Typescript because it might call untyped code but you CAN trust Purescript is just wrong. It's not even just wrong, it's utterly misrepresentative of what actually happens in Elm and Purescript. It's misinformation.

<comment><USER14> Could you elaborate? Why is it wrong/misinformation?

<comment><USER15> Not OP, but I'd guess the idea is that calling untyped code in TS is basically Pushing the Big Red Button, or Launching the Nukes™. When doing that in TS, you do it knowing it's your own responsibility to test and establish trust in the code. And Elm and PureScript are the same. In other words, Elm and PureScript won't save you from screwing it up the way you can with TS.

 _All_ pure/statically typed languages have escape hatches. It has been leveraged as a counter-argument to using them. But but but, they will say, Haskell has unsafePerformIO!!! Well, yeah, sure it does. You can subvert the borrow checker of Rust, too.

But you have to do it explicitly. You can grep your code base for "unsafe" (literally). You can lint for that. You can code review for that. You can document it. And that's what makes it OKish. In a way, types are like big fat oven mitts, and you're the lead programmer of a bakery, where you pop buns in the oven all day. You can discard the oven mitts for a time, though, and do whatever delicate work you need your actual fingers for. Just don't touch the hot stuff, lest you get yourself burned!

</comment></comment></comment></comment><comment><USER16> Companies and coders will always push themselves to the absolute brink, where they no longer trust the code and the system is nearly unmaintainable.

Because every step towards that line has not just cash value, but exponential cash value if it's a startup.

And by constantly pushing themselves into unfamiliar territory coders develop the most impressive possible resumes. They either have relevant experience or have experience in a tech even beyond what the company they are interviewing is using. That's your best position to get hired.

It's easy to write JavaScript you can trust. Heck, you can write a trustworthy web server in Visual Basic. Trustworthy code just isn't worth much to 99% of the players involved.

<comment><USER17> Sure, if you're going to dump your project in 6 months like a hot potato. Any coder that takes pride in their work knows that constantly piling on more tech debt to push thing out faster only slows down your project in the end. The only exception I can think to this is very early start ups, where if you don't get a product out in 6 months, then the project won't have a future to think about.

<comment><USER16> I think most companies do do this, on a rolling basis with different parts of the product.

Except by "dump every six months" it's more like "after six months don't add much to that anymore, unless we can dedicate a good three weeks to hacking it into place. And then dump the whole component in three years".

Since your customer base and business requirements are likely to turn completely over in 3 years this makes some (perverse) sense for a startup.

</comment></comment></comment><comment><USER18> It's a bit hard to follow what the author wants to tell us, so I might be misrepresenting below (sorry!). I don't think the assertions that (I think) they make hold though, or are particularly useful.

The author claims "functional programming, types, JavaScript: pick two". He supports that with links to a number of libraries that have incomplete type definitions, and a few patterns that are hard to express in a static type system.

I don't think that assertion holds. Some JavaScript APIs are indeed written in a style that's very hard to give static types for, and some libraries have sub-par type definitions.

But odd JavaScript APIs != the entirety of functional programming, and sub-par type definitions are just missing features that need to be fixed. You can write perfectly fine, statically typed, functional programming idioms within the TypeScript type system (and presumably within Flow). You can even do that within the confines of Java's type system, and that's a lot weaker than TS' or Flow's.

These type systems are optional, and you can subvert them. If you use the recommended strictness flags though, it's hard to do so accidentally.

</comment><comment><USER19> > In a dynamic language like JavaScript, it can be hard to know what the shape > of your data is.

You don't need static typing to program defensively. Static typing instead ensures a certain defensive position, but as a developer you can choose to program in such a way even in a dynamic language.

That being said it is foolish to make a blanket assumption that data is doomed to confusion. The state and shape of data is determined by the authoring application and reinforced by the receiving application. If data is shaped improperly then a defect is present in the system, so fix the defect.

If a dose of common sense is still not enough... then program in TypeScript.

<comment><USER20> It's nothing to do with "a dose of common sense" so much as it is the reality of dealing with humans. Humans make mistakes. Static typing is automated checks to make sure you didn't. When doctors start using checklists their patients do better [1]. Static typing is checklists for programmers.

In theory weak dynamic typing works great. In practice humans suck. Hence checklists.

[1] [https://www.newyorker.com/magazine/2007/12/10/the- checklist](https://www.newyorker.com/magazine/2007/12/10/the-checklist)

<comment><USER19> This completely ignores my comment in its entirety. Do people make mistakes: yes. Does software ever have defects: yes. Typically, people making mistakes in software is called a software defect.

It is absolutely critical in a discussion like this to understand that defects in software are not necessarily defects in data. This conversation is about data, and checks for processing data are already present in various forms. For example when was the last time you complained about weak type systems when working with JSON, XML, or SQL tables?

<comment><USER21> > For example when was the last time you complained about weak type systems > when working with JSON, XML, or SQL tables?

Well, I don't know about the person you're replying to, but I certainly complain about these all the time.

Interestingly and counter to your point, I think, XML grew a "type system" of sorts with XML Schema (which is widely used IME, esp. where interfacing with external services as in SOA), and SQL actually has a reasonably strong type system for most implementations albeit dynamically checked at query planning time. (SQLite seems to be the outlier here.)

JSON is actually the outlier here, but even with JSON there's been attempts at a sort-of type system with JSON Schema. Why? Well, because beyond a certain size the "just chuck some data somewhere in there" ceases to be workable when you want stable and maintainable interfaces between software components.

Ultimately type systems are invented and used for almost entirely pragmatic reasons.

<comment><USER22> > ... XML grew a "type system" of sorts with XML Schema (which is widely used > IME, esp. where interfacing with external services as in SOA) ...

The type system came from both XML Schema and XPath and was codified with XSLT 2, then expanded when XQuery was defined. It's not been a type system "of sorts" since XSLT 2, which filled in a lot of gaps and undefined behaviours.

</comment></comment></comment></comment></comment><comment><USER23> I love TypeScript and use it in any new project I create. The author is right though, you need to have team discipline to avoid using the `any` type when it can be avoided, and immutability is not in scope. TypeScript is probably the closest we'll get to my personal ideal of static typing in JS, while understanding that you sometimes need an escape hatch to deal with dynamic typing as JS is a dynamic language.

I think that the focus now should be allowing other more modern languages in the browser by means of Web Assembly. Rust is a great candidate for dealing with immutability and unsoundness concerns. I can't wait for wasm to be fleshed out more.

It does beg the question though, would web development be as ubiquitous and as popular if the core language in was statically typed? Does the freedom JS offer you allow greater adoption overall, meaning that it's beneficial to loosen the type restriction as the ecosystem will flourish because of it?

<comment><USER24> You don't need to wait for web-assembly to solve these problems.

TA mentions 3 languages (Elm, Reason & Purescript) that combine sound type- checking and immutability right now.

None of these bring the cognitive overhead of Rust's borrow checker and, in the case of Reason at least, compile at lightning speed to readable (though optimised) JS.

<comment><USER25> Purescript also has a nice escape hatch as OP desires because it has a native JavaScript ffi unlike, say, elm.

</comment></comment></comment><comment><USER26> Static types are great because they make certain classes of bug impossible to write, but they have their limits. There are escape hatches, like casts and Object types, even in statically-typed languages, though fewer of them in languages with more advanced type systems. There are reasons to like PureScript over TypeScript, just as there are reasons to like Haskell over Java. TypeScript doesn't give you a way to ban side effects, for example, being part of the imperative family of languages that it is. So if you are super into banning side effects you might like a language that does.

The thing to realize is that at the end of the day, all you are doing is reducing bugs, and while your type system (IMO) really can help reduce bugs, it will never catch all bugs. There is still value in a function declaring that its argument is of type User (and not defensively checking it) even if it is theoretically possible, _in the presence of a bug_ , though unlikely, that the argument is not really a User. The function has said what its precondition is, and (assuming you are validating any data that comes over the network or from an untyped source), this precondition will in practice be checked 99% of the time. If a bug happens to line up with a hole in the type system, you'll just have to debug and fix it.

<comment><USER27> All good points, but I'm having a hard time with this statement:

"There is still value in a function declaring that its argument is of type User (and not defensively checking it) even if it is theoretically possible, in the presence of a bug, though unlikely, that the argument is not really a User."

I'm trying to think of a statically-typed language that would allow such a thing, and I can't, so I assume that you're referring to TypeScript here where you have a world where things are "partially-typed" ?

<comment><USER28> In TypeScript you could also pass `any` as argument to such function and the compiler would be happy. Of course the noImplicitAny flag helps here, but sometimes you could get `any` from a library with poorly written types as well.

<comment><USER27> Yep, that makes sense, thanks.

</comment></comment></comment></comment><comment><USER29> One of the strengths of JS is how the runtime environment can be dynamically interrogated and polyfilled, and how it can often gracefully degrade if there's a mismatch between static assumptions and runtime behavior.

Is there a vision for how PureScript/ReasonML/Elm etc. can accomplish the same thing?

The brute force approach is to place a boundary between everything external and handle it via an FFI. This adds friction: apps built under this approach are less capable and evolve less gracefully. I hope there's a better solution.

<comment><USER30> Nim is another language with a JS backend and it is also kinda good at this: it has a pretty good type system, but it's easy to use it gradually for JS code.

You have a `JsObject` type (which is basically `any`) which lets you write your Nim->JS code in a dynamic way and cast to static types whenever you need to interface with static parts of your program. You can still also define the type signatures of a JS API as well and have a fully type safe experience, but you can do it lazily: just for the functions/types you need.

Basically you can use a JS api in any way you want: from almost fully dynamically to gradually more and more type safe way

</comment></comment><comment><USER31> Javascript is maybe the language made or suitable for simple app, If you will make a big complex app, There is a simple way to fix this: use more strong languages Compile to Javascript like Elm/PureScript/BuckleScript/ScalaJs/Nim/ClojureScript(with core.specs) and so on[1].

[1] [https://github.com/jashkenas/coffeescript/wiki/List-of- langu...](https://github.com/jashkenas/coffeescript/wiki/List-of-languages- that-compile-to-JS#static-typing)

<comment><USER32> Yes, that's exactly what the conclusion to the article says.

As someone who has (almost entirely) given up writing plain JS, my skimming of this article is "2500 words about issues with JS mutability, then: just use ClojureScript".

</comment></comment><comment><USER33> _But in JavaScript, the fear is always with you._

That's why we have both tests and code reviews.

Aside from that I'm surprised the author didn't mention checking constructors. It's arguably the most dependable way of checking if something is of a certain type.

But I agree that it's a shame that TS/Flow lose their ability to check types whenever partial application or currying is involved - it's not like it's impossible in principle.

<comment><USER20> I did Objective-C work for a decade under such conditions. It's never enough to have tests and code reviews. Static typing is strictly better.

<comment><USER33> I worked on a 150k LOC pure JS codebase for almost two years and my experience is different - if tests aren't enough then they're either not written well enough or there isn't enough of them.

<comment><USER20> Think of all the time you wasted writing unnecessary tests that the compiler could perform automatically on your behalf by you properly specifying your types. You'd be much more productive and confident, and have less LOC to maintain. Refactoring would be much easier too.

<comment><USER33> No type system would measurably help in this case since we necessarily had to deal with browser behaviour which wasn't exactly standardised and tended to change from version to version.

</comment></comment></comment></comment></comment><comment><USER34> Many of these concerns seem to not be limited to Javascript at all - especially once you're sending/receiving data between systems. In Python for example, when receiving JSON/XML payloads you have the same defensive parsing layer at the point of entry, but humans can still mess that up and monkey patch a class that breaks assumptions elsewhere without warning. Did I miss something in the larger argument?

<comment><USER35> The larger argument is that you can't have the "language level trust" until you push __everything__ trough the same comppiler/transpiler/validation pipeline and can trust that everything has gone trough it and it has not been modified by other means.

Using Javascript as a platform where you mix code generated trough different conventions and tools is a halfway solution. Javascript treated as the unmodifiable binary from the compiler creates same level of trust as using other languages.

Technically:

* In C++ somebody can use different header for the class and break the class abstraction.

* In Haskell some library might go trough the FFI into the runtime and assign values to data in non-functional way and break the functional abstraction.

* In Python and Java there are ways to access data in ways that circumvent the compiler or the language semantics.

The difference is how strong the convention against doing so is and does breaking the abstraction have any benefits.

</comment></comment><comment><USER36> After watching the value of values by rich hickey I've become cynical towards complex types, I think my ideal would be maps and scalar types and maybe something like clojure specs for more complex checks

</comment><comment><USER37> I think shortcuts like the following are fundamentally flawed, at least when dealing with user input.

      If (user && user.name) { ...

While it sucks to have to even check for user etc, not checking that it's truthy, then an object, then checking that the name is the correct type also during runtime, will cause bugs over time.

This type of developer provided shorthand validation is pretty much the cause of all hacks/data breaches currently. It's more of an attitude or how a developer prioritizes their own wants/needs over maybe a client/end user. Like I mentioned in another comment, checking for more advanced, abusive behavior will make issues with type checking seem basic in comparison.

<comment><USER38> Will be nice when JS gets the Elvis operator and you'll be able to do 'if (typeof user?.name === "string")' which will have the added value of type narrowing/interaction with 'never' if name is expected to be something else.

<comment><USER39> I'd say the elvis operator would make things worse, especially wrt the parent post.

The problem isn't that `user && user.username` style validation is verbose, but that it's very error-prone. Making it less verbose just means you'll more likely use it before you reach for a better validation strategy, like a declarative validation library.

</comment></comment></comment><comment><USER40> The author of this article also has a great talk in on the subject:

[https://youtube.com/watch?v=IvPBMEYxP-Y](https://youtube.com/watch?v=IvPBMEYxP-Y)

<comment><USER41> will verify this was a good talk

</comment></comment><comment><USER42> But you still have to validate and parse unstructured data in Haskell as well. And what would be the point of having the type checking done at run time? That's what many dynamic programming languages already do. If you're curious about Flow or TS then you must already have a problem with that approach.

Type checkers are tools that help us reason about, structure, and correct code. That's all.

Flow is decent these days but will probably never be as powerful as Haskell. My only gripe is that it forces my team to write verbose code at times in order to gain the benefits: you lose point-free style, gain a bunch of identity and instance checks... but it's a small trade off to make.

One small trick worth remembering and using in Flow to gain something similar to exhaustive type checking is to cast to the _empty_ type in the default case when pattern matching on a type[0].

It's not an elegant type system but if you have experienced a good type system (like Haskell's) then it does make using Flow/TS much easier.

[0] [https://medium.com/@ibosz/advance-flow-type-1-exhaustive- che...](https://medium.com/@ibosz/advance-flow-type-1-exhaustive-checking- with-empty-type-a02e503cd3a0)

</comment><comment><USER43> > In a dynamic language like JavaScript, it can be hard to know what the shape > of your data is.

Being dynamic doesn't preclude variables from being type checked by the runtime. Reading this just sounds like "javascript has no built in support for type checking, so lets pretend it's not possible"

All the time people spent making weird unreadable 'fat functions', but you still can't define the types of arguments you want to receive?

<comment><USER6> > Being dynamic doesn't preclude variables from being type checked by the > runtime.

It kinda does, because in a dynamically typed (as colloquially defined - <USER2> you want to debate that definition, that's another discussion) language, variables don't have types - values do.

<comment><USER43> Ok, if you want to be pedantic about it, fine.

Nothing precludes _values_ from being type checked.

<comment><USER6> Type checked against what, if a variable doesn't have a type?

There are contexts in which two values are involves, where we can at least check that the types are matching (or reasonably compatible), like (a + b). JS is a massive failure in that regard, too, and there are dynamic languages that do it far better - e.g. in Python, ("1" \+ 2) is a runtime type error, not 3.

But in the context of this thread, I feel that's not what we're talking about. We're really talking about contracts - and contracts require typed bindings (variables, function arguments etc), not just typed values. Which means that they do require static type annotations. As we've discussed in another subthread, those annotations might be _checked_ dynamically - but they still have to be declared statically by the coder, which makes the type system effectively static from their perspective.

To put it differently: if you require types to be declared explicitly, there's no reason to _not_ check them statically. Dynamic checking of static types really only makes sense for gradual typing systems, where code with static type annotations might be called from some non-annotated code, and you want it to be possible without forcing static typing on the caller. At that point, yes, you can have a dynamic type check in the callee, which ensures that if code without type annotations doesn't actually get the types right, things fail fast at the static/dynamic typing boundary, instead of allowing it to propagate into the statically typed code (as is the case in e.g. TS today).

<comment><USER43> > if you require types to be declared explicitly, there's no reason to not > check them statically.

I think some of this thread is suffering from confusing terms so, my entire point is this:

There is no native way in javascript to say that the first argument of function foo must be an instance of class Bar (which in JS could be a string or an array or some custom object or even a DOM element - everything is an object and thus has a 'class').

The common response is "use typescript" which means you write the code with argument type declarations, and then compile to javascript. This (in theory) means any code you've written in the project in TS which calls our foo() function, will warn/error if the first argument isn't an instance of class Bar.

But, and this is the problem: it's not enforced by javascript, it's "enforced" (for whatever definition of enforced typescript uses) by the TS compiler.

So if I then use the compiled JS of function foo() and call it from native JS (i.e. not compiled by TS) - it won't tell me I have the wrong type.

 _THAT_ is my issue.

<comment><USER6> Yes, I understand that. My point was that it's not really dynamic typing at that point anymore. It's kinda like C#, where you do have "dynamic", but there are static type annotations that code utilizing "dynamic" can validate against. At that point, I'd say that it's no longer a dynamic language in conventional sense.

Getting back to your issue - it's a pragmatic decision for TS, because enforcing its type system efficiently is virtually impossible on top of the JS _runtime_ type system, when you consider how it has to work. It sounds like simple, obvious check for trivial cases, like if I annotate a function argument to be an number or a string. But what if it's an interface? At that point, the runtime check must ensure that 1) it's an object, 2) it has all the members listed in the interface, and 2) they have the corresponding types. If they are themselves interfaces, this becomes recursive. If they're arrays or maps, then this has to be done for every element. An array of arrays is O(N^2) already!

To check it efficiently, you need to have proper runtime type tags - an array has to _know_ that it's an array of number, not just an array. Then the runtime checker can just query that, like it does in Java when you, say, downcast Object to int[]. But TS has to work on top of JS runtime, so any such runtime type tagging would manifest as visible artifacts in JS; and TS is intentionally designed to be "invisible" from JS interop perspective.

If we want quality strong typing that works properly with cross-language interop for the web, we need to throw away the JS runtimes entirely (it would be a good idea in any case - it's an atrocious object and memory model for anything other than JS itself), and replace them with something saner.

</comment></comment></comment></comment></comment></comment><comment><USER13> This article is bizarre. Firstly, the author states the problem that data can propagate and suffer loss/mutation over time. He then cites types (which absolutely do solve this problem), but then dismisses them saying:

> Adding types to our example doesn't solve the underlying problem. It > improves trust within the code base by helping to ensure that data is used > consistently, but it says nothing about data received from the outside > world.

But anyone who's used type-based programming knows this is nonsense if you simply write a typed parser (of particular interest to gradually-typed Javascript is packrat-style parsers). Then, your code needs to specify what it wants and what its policy is if it doesn't get it.

But if the author was imagining that compile time integrity and correctness checks could EVER perform runtime checks... well... they're not even wrong they're misunderstanding the function so badly.

The author then proposes out of left-field:

> But it's like plugging holes in a leaky ship. The problem isn't just that > you can't trust the types in your system, but that you think you can. You > rely on the types to tell you when a change breaks something, but because > they were quietly disabled by an any type, or by use of a library, or by a > soundness issue, it doesn't. Types in JavaScript are different from types in > most other languages people use: They can't be trusted in the same way.

Which is both true and useless. Yes, it's true that type circumvention methods exist, and you never really can know if you're calling into a library that circumvents your type constraints unless you read the code. But yes, that's useless because _nearly every typed language also has this mis /feature, including OCaml, Haskell, C++17 and even Rust!_ So the author is not actually giving a real recommendation or even novel insight.

And then we get the final substantive giving us arguments that the author has themselves just discredited:

> Or you change the game and just use PureScript. Or ReasonML, or Elm, or even > ClojureScript. These exist today. Production software runs on them. They > work with the JavaScript ecosystem, where necessary. And they provide a > higher base level of trust in the code that you write and an environment > where immutability, functional programming, and types (where applicable) > work well and work together.

Firstly, I've written a fair amount of Purescrpt and _we call into unsafe code ALL THE TIME for the sake of expediency in Purescript._ To even pretend otherwise is just... either it's willful lying or someone who has barely interacted with the Purescript ecosystem in any production fashion.

If you use a dependency and don't vet it somewhat (or at least trust a crowd to vet it as a minimal effort) then you're in for a bad time. Pretending otherwise, or that this is a unique flaw of Javascript, is just wrong.

And if you disagree with that, then I have a challenge for you. I propose to you that you can substitute ANY language and runtime's type and GC as "types" and "assembly" as underlying javascript and not change any underlying axiom presented in this article.

</comment><comment><USER44> The article builds a strawman.

It's not the types that fail, but the type system and its misuse.

> _This is like pretending really hard_

No, that's not pretending — static typing is literally about theorem proving, type theory being equivalent with math logic. This is the famous Curry-Howard isomorphism, types corresponding to propositions.

Of course, you can have situations in which your type system cannot describe the propositions that you need, or situations in which holes are left for pragmatism. Such holes include for example the ability to use Object and then downcast in Java and have the implicit contract that the people using them know what they are doing, being at the same time a symptom of the type system not being expressive enough.

In TypeScript in particular you can just use the "any" type, which is there for pragmatism and because JavaScript developers would have had a hard time adopting it otherwise. It doesn't help that TypeScript's generics are _unsound_ either.

Of course, you can point at "the outside world" and say that you can't trust it to deliver the types that you expect. But with a good type system, you only need to do that runtime validation only once, at the edge where you receive the data and afterwards the statically typed compiler can take over that responsibility. And indeed, in my experience libraries for JSON parsing in Scala (e.g. Circe) or Haskell (e.g. Aeson) are very well behaved and due to automatic deriving, they make that validation painless in 90% of cases, because the runtime validation is derived from the static types automatically, no work required, something I haven't seen in TypeScript.

The whole notion of " _optional types_ " is my opinion _flawed_.

You either work with static typing, or with dynamic typing and choosing a side will change the way you work, it will change your mentality, your approach to problem solving.

Working with optional types, which is what people tend to do in languages like TypeScript, brings you the very worst of both worlds.

Optional static typing doesn't work. A contracts system, like Clojure's Spec, works much better for dynamic typing and yes, there are fundamental differences, basically the difference between " _for all_ " and " _exists_ ", or between compile time and runtime.

\---

> _Convention: Pretend immutability_

N.B. in an actual FP language, immutability is not a convention, but something being enforced by how data structures are built (e.g. persistent data structures), via the type system or the runtime system — even in Java, you'll have a really hard time to change the definition of a class or of a "final", or to mutate a persistent collection (see vavr.io).

\---

I like TypeScript overall, I think it's an improvement over JavaScript and it certainly has pretty cool features — but don't use it to judge either static typing or dynamic typing or functional programming for that matter.

If you want to see actual dynamic typing and how it can shine, use ClojureScript. If you want to see actual static typing and how it can kick ass, use PureScript.

And both are good for giving you a real taste of functional programming. JavaScript and JavaScript++ languages, are really poor at FP, mostly due to the ecosystem's culture, and the very few FP libraries that exist for JavaScript are very unpopular, with only a few gems here and there, like Rx.JS. So if you're doing JavaScript or TypeScript, chances are your codebase doesn't do much FP.

<comment><USER45> I instead proclaim that it brings you the best of both worlds. Finding the right mix of static/dymamic is a balance act but if you do so you get the benefits of static types (safety, documentation, tooling) and dynamic types (fast prototyping, not having to write convuluted code to please the compiler). What are the killer features that gradual types lose out on?

<comment><USER6> As the old saying goes, "there's nothing more permanent than a temporary solution".

In the context of software development, it means that "prototypes" get shipped as production code all the time.

<comment><USER45> Sure,and lots of codebases are completely untyped. I find it great that you can opt out of the theorem proving that type checking is when crunch time comes. As such it functions as a loan and your organization should strive to pay back the debt when it can. Nothing can save you if you never get a calmer period.

</comment></comment></comment></comment><comment><USER37> I agree that defensive checks may clutter code, but in the current landscape of constant security issues, to not use a battery of defensive checks whenever dealing with input is simply naive, no matter the IDE, compile language or runtime language.

<comment><USER37> To help with readability but allowing for complex input checks, I typically abstract the input validation to another function, called near the top.

I think as time goes on type checking will be the least of our issues. Checking for different types of abuse (technical, social, semantic), context sensitive boundaries, setting tripwire-esque traps to control abuse etc will make any current concerns over type checking seem elementary.

We need to give up on the idea of coding 3 line, beautiful functions that look great on Twitter and realize we live in a time where defense and privacy are a priority, while (some how) simultaneously pushing innovation.

I hate it, trust me, but if you talk to typcial corporate/business clients, this is where their thoughts/concerns are currently. I realize it's a bigger conversation than what I'm mentioning here.

</comment></comment><comment><USER46> _As developers, we want to reduce fear of our code failing and increase trust in our code working well. ..._

The author doesn't mention the critical need for any nontrivial JavaScript project to build and maintain an automated test suite.

</comment><comment><USER47> This article explores a lot of things bundled together. One morsel to take away is the bit about inbound data validation.

Type systems needs to work statically as well as at runtime via some kind of reflection API. This way you can unmarshal the data that comes over the wire directly into your language's type system. With JavaScript+TypeScript/Flow, the static type system and the dynamic reflection system is split into two separate paradigms, which in my opinion makes things rather complicated to the point of sacrificing developer productivity.

</comment><comment><USER48> I'm not really sure what the author is getting at. You need discipline to avoid most of the garbage that can be created by using any language or framework.

I've seen some of the worst java apps before, but no one says "never use java, it's bad".

It's generally accepted that skilled engineers can make clean, easily maintainable apps, and unskilled engineers make garbage apps.

This just sounds like sloppy engineering and a total lack of professional rigor and in that case, why is javascript to blame?

</comment><comment><USER49> It's interesting this article makes a very similar point as a comment I made a few days ago about trusting developers: [https://news.ycombinator.com/item?id=18255777](https://news.ycombinator.com/item?id=18255777)

</comment><comment><USER50> This is why I love async code, at every step I get either an error or a value. Which lets me deal with the error gracefully. I don't think error handling is "clutter". Not trusting code is an under-statement. You should be paranoid!

</comment><comment><USER51> Not sure what this author is saying here. Types have nothing to do with being able to trust other systems and everything to do with the internal formal consistency of the code that _you write._

It's about being consistent with yourself.

If you find yourself writing defensive checks in fulfilled promise handlers because the data you get is sometimes invalid, stop. Get up from your keyboard, go to whoever owns the endpoint, and ask them why their endpoint is returning a 200 OK response with data that doesn't live up to its spec. This is a bug in their system, not yours.

<comment><USER52> If your software crashes on bad user input, that's an error in your software.

By the way, there is distinction to make between library code that should exception/assert/abort on error and application code that should verify input and display an error to the user.

<comment><USER51> Correct - but in the case I described above, you (and your program) are the user.

<comment><USER53> You've clearly had a blessed and gentle career

<comment><USER51> I've worked for very large companies whose massive codebases are littered with defensive checks that have piled up over many years. Invariably, I find that this is because, when the initial wave of defensive checks inevitably broke down because they guard against something that itself changes behavior again, more defensive checks were added.

All of this could have been avoided if those companies had just created a culture, from the beginning, where you force the upstream data provider to fix its issues rather than coding around them by allowing code to fail-fast rather than gracefully.

Now companies are beginning to introduce integration and unit testing across the board and type systems (again, to ensure _internal consistency_ for systems so that _other_ systems can depend on them) and the cruft and defensiveness is slowly going away.

To repeat the old cliché, the best defense is a good offense :-)

<comment><USER54> >had just created a culture, from the beginning...

Were it such an easy thing...

Here's how I've experienced such things:

I write naive code. Application hard fails. Test environment down - <USER3> cross with me.

Me: Yo upstream - fix your data please.

...no response.

So I raise a ticket to get data source fixed - send it to the backlog.

Me: Yo delivery - can we get this ticket prioritised, assigned and put into a sprint?

Delivery: Yeah... nah - cause y'know... delivery.

Me: Yo leadership - can we get a decision taken on whether or not upstream should fix their data, or whether we should just program defensively? If the former - can someone tell delivery to tell upstream?

...no response.

At this point - I give up. Write my little defensive check and admonish myself to do so consistently from now on. Commit, push... go home - sleep like babe.

</comment></comment></comment></comment></comment></comment><comment><USER55> The author seems to confuse static code analysis with runtime values.

</comment><comment><USER56> Is having to use something like a json-like schema just admitting that the language is broken? If you can't trust or use common practices inherent to the language to do things in a typed way if needed then what is the point of a not strongly typed language?

<comment><USER37> To be honest, just having a defined, literal type is not going far enough.

Is there a built in language strategy, in Rust for example, to define a complex numerical type that has common properties like min/max range, exclusive min/max, conditionally required logic etc?

Of course you can put some custom checks/logic to validate, but not sure why people instantly shame json-schema. From a validation perspective (not tooling) typescript is simplistic compared to a reusable, extended json schema.

It may be a matter of time for other js/ts tools to improve. I've been learning Rust and I haven't seen a better solution currently for runtime/user input validation. (Not a c/rust expert by any means)

<comment><USER57> Currently, you do runtime checks. We've accepted an RFC for integer generics that will let you do compile-time checks instead, but we're still working on an implementation.

<comment><USER37> Thanks Steve

</comment></comment></comment></comment><comment><USER58> First, no language is perfect, and building a real system with growing team(s) is always about making purity vs pragmatism tradeoffs with the main goal of keeping the complexity down as the system scale. The truth is that a system is much more than just the languages it is composed of, and regardless of the purity, exactitude, elegance of a language, sloppy work will always lead to a messy result.

In other words, languages should not be used as a substitute for discipline, good patterns, or scalable best practices, but rather as an enabler of such conducts.

TypeScript favored pragmatism over purity, but it is a very well thought-out, robust, and expressive typing layer on top of JavaScript.

Sure, for the sake of language purity, developers can "bytecode your way" to JavaScript Dart, Java with GWT, ReasonML, Elm, but there is a reason why all of those options, how elegant they might be, have limited traction and relatively short lifespan (at least compared to JS), and that is because they add too much friction points (often unexpected ones) for the sake of language purity, which at the end is a never-ending quest anyway.

TypeScript is a structural typing system which has its differences with commonly known nominal typing systems (which often confused with soundness), and while there are some unsoundness is some specific cases, overall, TypeScript is a very robust and expressive typing system on top of the most pervasive language, JavaScript. Not perfect, but very robust nevertheless and a huge step up from traditional JS. TypeScript combined Modern JS (module, let/const, async/await/promise, arrow function with related scoping, deconstruction, ...) does create a very robust environment to scale code and developers.

We used to all our backend in Java for 20 years (personally comes from Oracle) and we now see nodejs / typescript ecosystem and runtime environment has competitive for big app system. For one of our client, we actually just ported the last of our multi-service system from java to TypeScript, and it got 40% less code and it is better typed than Java. Java's high typing friction and Class-For-Everything purist approach makes good code design more of a contortionism exercise than an intellectual one, and while nowadays most agree that this OO-Obsessed approach was the wrong one, it was considered very pure and "robust" at a time.

Anyway, the short version is what makes a big code base scale is not the purity of any given part (e.g., language) but how the whole can minimize present and future friction points. The less friction, the more velocity. Discipline, best practices, tools, environments, and ecosystem are all part of a whole and one needs to make sure to not over optimize one part on the detriment of the others.

</comment><comment><USER59> Obligatory link to Destroy All Software talk about types: [https://www.destroyallsoftware.com/talks/ideology](https://www.destroyallsoftware.com/talks/ideology)

<comment><USER60> pretty cool, just learned about destroyallsoftware

(long term lurker here)

</comment></comment><comment><USER61> Broken promises in Javascript? ... unsurprising ... Here is an imaginary article that I would read: "New web platform runs entirely in webassembly generated by well-typed languages". Subtitle: "When hand-written Javascript is detected, continuous integration activates subdermal shock-collar that each of the developers is contractually obliged to have".

<comment><USER62> Just make sure the Promise has a Catch to handle errors.

Err...you're talking about promises from the community, not Promises in code.

</comment></comment><comment><USER63> It fails all with the teams opinions. It's the people not the language or tools. All these discussions of developers trying to be correct. You don't need typescript, flow, functional programming, OOP, whatever. These tools have it's place particularly because teams cannot work together and need some kind of rules. In most cases individual developers differ quite a bit from each other, especially when it comes to their opinions. It's dramatic.</comment>


GoPro is recalling its Karma drone - <AUTHOR> http://www.theverge.com/2016/11/8/13569730/gopro-karma-drone-recall-announced?utm_campaign=theverge&utm_content=chorus&utm_medium=social&utm_source=twitter <comment><USER2> More distressing for GoPro is that they've only sold 2500 units so far. This product was hyped for a couple years.</comment>


An interview by a 7th grader - <AUTHOR> http://paulgraham.com/int.html <comment><USER2> _If you're good it's always easy to find programming jobs. Even when the economy is bad there is a shortage of good programmers._

That's a truism in our industry that far too few people understand, much less take advantage of. If you're good, you don't need to worry about your career all that much. You can go off and travel, join flaky startups, and otherwise sabotage your "career", and know that if it all falls apart you'll land on your feet. So long as you're demonstrably good at what you do, you can always pick up a good contract on short notice.

There's a flip side to it, of course. If you find it hard to get work in this industry, you might want to consider the possibility that maybe you're not quite as good as you think you are.

<comment><USER3> Isn't that true of any career though? As a college student who will soon be attempting to get a job (presumably as some sort of software developer, since I'm a CS major), I don't think saying "you'll find a job if you're good" really tells me much. I don't KNOW if I'm good. I'm confident in my comprehension of Computer Science topics, my ability to learn and find out things I don't know, and my ability to present myself well in an interview. Will that be enough for an entry level job?

<comment><USER2> Your "good"ness will present itself to you over the course of time. You'll be working at a startup and they'll lay off the entire development team, but ask you (and only you) to come back on a contract. You'll get a call out of the blue from somebody who's putting together a team and got your name from one of your old bosses who recommended you. These incidents might not mean much individually, but over a half dozen years you can assemble them to mean that you're good.

From there, you get something that's definitely not true of any other career (or at least only applies to a few). Doctors and lawyers generally don't get to disappear on year-long vacations and then drop back into their previous career path without missing a beat. Developers can. You can go on to lead the life you want, without having to think about how it will damage your career. It's all good from there.

</comment></comment></comment><comment><USER4> >when you write a good program you get the same feeling of achievement you'd get from making something like a piece of pottery or a house

I get the same feeling writing good software now as I did when I built cool stuff with Legos and Knex when I was in younger.

<comment><USER5> Same here about the LEGO. And I get the same feeling looking at a piece of good source code I do looking at the sheet music to a great song. Actually all three systems can have a kind of beauty to them, visually, in their patterns and they can either ring right or ring wrong.

<comment><USER4> Play with some set of Legos long enough, and you're bound to come up with something cool.

</comment></comment></comment><comment><USER6> I don't feel the answer really apply to a 7th grade, but I still find the answer interesting. Of course, it's PG so lots of the answer were about startup which is a bit confusing. I stay that because, to the question: "What's the range of salary of a plumber?" Well, a plumber building a new kind of tools could get billionaire which isn't really answering the question.

Still, interesting read way better than apple evilness and "why my kids like ipad".

<comment><USER7> Still, answering ANY salary range question with "... or you can start a business" is such a refreshing outlook! Certainly not one I was exposed to in 7th grade.

</comment></comment><comment><USER8> > For bad programmers, like bad cooks, the mere mechanics of programming are > challenging. Whereas good programmers, like good cooks, can make whatever > they choose, so for them the big challenge is deciding what to make.

I've always loved the analogy of coding to cooking... a lot more than painting, or architecture.

<comment><USER9> I've just realised that I cook like programmer (or program like a cook). I take a recipe, then cook it multiple times changing different variables (iterating) until I'm satisfied with the results (shipping). The best thing isn't the food, but that you shipped something in a few days ;)

<comment><USER10> And the best part (just like programming) is that with experience comes the ability to alter the recipes/variables and reliably predict the results, instead of stabbing randomly in the dark.

</comment></comment></comment><comment><USER11> _> 2\. What is the worst part of being a computer programmer?

> For me the worst thing about programming is dealing with external > constraints... Often things you're told to do, and the programs your program > has to cooperate with, are confusing or stupid.

> 10\. What is the future direction of computer programming?

> ... programming seems to be changing to one in which you plug together > programs written by other people..._

So, according to that and in agreement with my own experience, everyday programming has more of its worst part...

</comment><comment><USER12> I'm curious to know how that 7th grader heard about PG. It doesn't really matter for the Q&A, but I'm still curious.

I'm guessing that either a Google search with "computer programming"-type keywords return's PG's page, or that it is via a real-life relationship...

<comment><USER13> I found PG by looking up the Wikipedia article on "Nerd" and going down to the external links, where his "Why Nerds Are Unpopular" article is.

<comment><USER14> I found PG by googling "why" a day when my life was particularly miserable, and came across the same essay. It was number 2 in the search results.

</comment></comment></comment><comment><USER15> Not to be nitpicking either, but this is not an answer to the question:

> What improvement does computer programming give for human life?

Computers are so widespread now that there is practically no aspect of life that isn't affected by programming.

(Kid specifically asks for 'improvements', not 'affected'.)

</comment><comment><USER16> I'm not familiar with (presumably) the American education system. How old is a seventh grader?

<comment><USER17> Usually 12 or 13.

</comment></comment><comment><USER18> Not to nitpick (I love the answers), but is this true?

> ...and we have drugs today that we couldn't have had in 1950 because > programs were needed to discover them.

Probably just my ignorance. But do people in biotech think that software itself is helping them discover drugs? Googling for 'biotech' and 'programmer' doesn't seem to answer the question immediately. Just curious. I imagine we're nearly there, if not there completely. And that the molecules involved are fairly complex -- but I didn't know that we were that dependent on computers for biomedicine. Any examples? There was a recent article about mapping the human genome being less than a panacea. Maybe there are some good examples though....

(Fwiw, the reason I nitpick is that it might be the wrong way to look at it. Software helps researchers discover and produce new drugs. But it's important to distinguish that from software actually discovering new drugs. Seems like a small point -- but it's actually a very different emphasis. One can, for example, lead to an AI winter, if the focus is on producing this amazing self- sufficient software, instead of thinking about it as a tool. But maybe we're already there with biotech, I just don't know...)

<comment><USER19> <http://en.wikipedia.org/wiki/Virtual_screening>

<comment><USER18> Very nice, thanks. Here's a somewhat related article too:

[http://www.voiceofsandiego.org/science/article_4b79fc5d-4d5e...](http://www.voiceofsandiego.org/science/article_4b79fc5d-4d5e-5395-a771-1ed6fed3952a.html)

On the other hand, it sounds like VS isn't exactly at 100% production yet:

[http://wavefunction.fieldofscience.com/2010/04/will- virtual-...](http://wavefunction.fieldofscience.com/2010/04/will-virtual- screening-ever-work.html)

But getting there. Based on your HN profile, I defer to you obviously. Curious subject. E.g., based on the wikipedia article, I had no idea the range that Berkeley DB was being used for...

</comment></comment></comment><comment><USER20> Awesome points. I agree with giving the programmer all the uninterrupted time to hack. As a matter of fact, allowing someone dedicated to his or her project to work without unnecessary intervention applies across the industry board. When you're in the zone, there's definitely no stopping you - and best to keep doing what you're doing while the creative juices are endlessly flowing.

</comment><comment><USER21> I love posts like this! Great answers, pg. Here are mine:

 _1\. What are some qualifications of a computer programmer?_

The two most important qualifications are a love of details and a simultaneous appreciation of the bigger picture. You have to understand the landscape that your software will fit into. Then you have to be willing and able to dig down deep and be comfortable building stuff at the lowest level of detail. This takes a great deal of logical thinking, attention to detail, and personal focus.

 _2\. What is the best part of being a computer programmer? The worst? The most challenging?_

The best part is getting something working for the first time where nothing was there before. For me, this is so exciting that I still I do a "happy dance" every time. The worst part is the long hours alone. There's really no way around it; good software takes time and almost everything is done by someone alone at a terminal. The most challenging is finding a project big enough to not be boring but small enough that's it's too difficult to make good progress.

 _3\. What's the salary range in this career?_

As an employee, $35,000 to $200,000. As a company owner, $0 to billions. Either way, the range is very wide and depends on many factors, some outside of your control. Like any other profession, you should be a programmer because you love to program, not because of how much money you'll make.

 _4\. What is a typical day in the life of a computer programmer?_

I bet there are as many typical days as there are programmers, so I just share mine. My day starts at my terminal, making changes to my current program based the mark-ups I did to my hard copy in bed the night before. I spend most of the day at the terminal writing code, changing it, trying it out, and taking occasional notes. I avoid interruptions as much as I can. I have a regular lunch and dinner and some social life, but not too much. Every day ends the same, in bed with whatever I worked on that day, reviewing and marking up. Incredible attention to detail is required and this is how I do it.

 _5\. What is some advice you would give to young computer programmers?_

Just build something. Nothing can be more important. Whenever you need to learn something, find a way to learn it, whether it's a class, friends, or more likely, a book or website. It you want to be a programmer badly enough, you'll find this approach natural. If you don't, you won't.

 _6\. Is it easy to find a job as a computer programmer?_

If you're good (and can prove it), yes. It not, not so much.

 _7\. What was your most exciting project?_

A computer program that wrote other computer programs.

 _8\. What skills do you think young programmers need for the job?_

The ability to think clearly and logically, good written and verbal communication skills, the discipline to keep working when they'd rather be with other people, and the determination to see something through to completion.

 _9\. What improvement does computer programming give for human life?_

Computer programming makes software that frees people up to think about and do things that weren't possible just a few years ago. The possibilites for those people are endless.

 _10\. What is the future direction of computer programming?_

This is always hard to predict, but I'd guess the direction will head away from writing all of your own software toward connecting a lot of already written software to accomplish the same thing.

 _11\. Would life be a lot worse without computer programming? How much? Why?_

Just compare life in a country with advanced technology to one without. Computer programming doesn't have everything to do with the difference, but it does have a lot to do with it. Much of today's advanced lifestyle has resulted from modern technology. Much modern technology came from software. All software came from computer programming.

[EDIT: Changed "Most software" to "All software" in #11. Thanks sundarurfriend. Duh.]

<comment><USER22>
      A computer program that wrote other computer programs.

Sounds interesting. Can you share more details about it (if possible)?

<comment><USER23> It's called metaprogramming.

<comment><USER22> Err ... Okay. If he meant that, I read too much in to it and was thinking something at a completely different level.

</comment></comment></comment></comment><comment><USER24> > 6\. Is it easy to find a job as a computer programmer?

> If you're good it's always easy to find programming jobs. Even when the > economy is bad there is a shortage of good programmers.

I would add, well, in case you find it hard to find a decent job, you can always start your own startup, (if you will apply to YCombinator, you are going to find it even more fun).

</comment><comment><USER25> Good answers and I applaud the effort given, but the questions feel like they were copied out of a textbook or teachers example and the word "programmer" inserted.

I think I would have tried to relate to kids today by explaining that someone has to write the complex video games they play and the browser they use to waste time on all their internet sites.

</comment><comment><USER26> What's the date on this essay? Most of the other essays say the month/year at the top.

</comment><comment><USER27> I misread that as "An interview with a 7-year-old" the first time around. (Or to be more precise, I read it as interview, 7, Paul Graham and filled in the blanks incorrectly.)

I like the questions and answers, though! Especially this sentence:

> The best programmers are the ones who are not only good at translating ideas > into code, but who have the best ideas.

It was especially good timing, too, because I've been spending a lot of time learning about how to judge the quality of ideas lately, and what effect the quality of an idea has on a programmer's motivation.

</comment><comment><USER28> <<So it is becoming more important to know what other programs you can use as building blocks and how to stick them together, and less important to know how to build basic "plumbing" yourself.>>

The sad truth :'(

</comment><comment><USER29> Reading the title, I thought I would find a totally different interview, kind of disappointing. Why does a 7th grader care about salary range (unless he wants to start _really_ early). It seems he/she just used some questions from another interview.</comment>


The village that changed China forever - <AUTHOR> https://www.youtube.com/watch?v=wEnE3AOrEL0 <comment><AUTHOR> That was 40 years ago. I read about this movement from William Easterly's Elusive Quest for Growth when I was young, still in college. It changed almost everything I thought I learned about poverty and development economics.</comment>


The Node.js Ecosystem Is Chaotic and Insecure - <AUTHOR> https://medium.com/commitlog/the-internet-is-at-the-mercy-of-a-handful-of-people-73fac4bc5068 <comment><USER2> Note: From March, 2018.

Discussions from the original posts, for those who are interested:

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

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

</comment><comment><USER3> If developers cared about security or their users they would managed their dependencies directly. Most developers don't cared because they don't wish to be inconvenienced.

That isn't primarily an ecosystem problem. It is a bad developer problem justified by common practice.</comment>


Anti-adblock startup secures $400,000 funding - <AUTHOR> http://www.theguardian.com/technology/2014/mar/27/page-fair-anti-adblock-startup-funding

<comment><USER2> Doesn't the presence and popularity of adblockers and anti-trackers give these morons a sense that what they're doing isn't wanted (pushing advertisement everywhere)?

It's sort of like telemarketers and do-not-call lists: if you're such a huge horse's patoot that people pass laws against your behavior, it's a huge hint to change that behavior.

<comment><AUTHOR> Few sites can make a subscription model work, advertising is the main income for most.</comment></comment>


Maybe Mark Zuckerberg Should Listen to These Canadian Hipsters - <AUTHOR> https://www.bloomberg.com/news/articles/2016-10-24/maybe-mark-zuckerberg-should-listen-to-these-canadian-hipsters <comment><USER2> I don't get it, they use facebook to start there own facebook channel to sell/trade stuff with other people on facebook. Sounds like they are using facebook as intended?</comment>


Final Fantasy comes to Ouya - <AUTHOR> http://www.kickstarter.com/projects/ouya/ouya-a-new-kind-of-video-game-console/posts/278237 <comment><USER2> I don't get the negativity on HN for this project.

This team is trying to disrupt a truly oligopolist market - I really hope they do it.

Give them a break on marketing announcement dissection at least until you see what they build.

<comment><USER3> Actually, the problem is that the market they are disrupting... doesn't exist. There's a mistaken idea in the public right now that Ouya can (or will) replace dedicated consoles. That's not even remotely true. The system simply does not have the power to be that device in your home.

Gamers seem to have backed this based on an idea that it's a $100 full fledged console. It is not. It is, at best, a tablet that hooks up to your tv and has a controller. At least as far as the hardware is concerned.

On top of that, their release timelines aren't even remotely realistic. March? They don't even have their online store prototyped yet. They have some UI mockups and that's it. Launching in March? Yeah right.

And then there's the issue with allowing the console to be fully open, using a hardware platform that is already having so many issues with piracy that developers are slowly being forced to release their games for free and supported with ads to make any money.

I have no doubt that if this system ever materializes, it will make an impact, but it's a long stretch to think you'll be taking delivery of this system in March and playing Final Fantasy 3 on it.

<comment><USER4> It's important to have good skeptics critiquing your product visions. Particularly if they are knowledgable and well intentioned.

With a big vision like this, it'd be concerning if everyone was just cheerleading them on and being yes-men.

The realistic prospect for a product success is rarely heavily scrutinized. And success rates are always statistically quite low.

Mr Charles raises some valid doubts about launch time. They're most certainly not a stretch - considering the tons of horror stories about launching hardware products we've seen on HN.

Let alone attempting to create a whole new market segment in a highly competitive environment - where even with success - making money might be difficult.

<comment><USER5> "well intentioned"

That's the problem. I'm not sure how a reasonable person can read the outright venom displayed in comment after comment all over the internet and then with a straight face say that it is somehow well intentioned. I don't know why so many people hate anything different that threatens the status quo. I guess it's just human nature. The phenomenon seems to manifest itself particularly in the consumer tech space though. The incumbents get praise heaped on them for doing little more than tweaking and renaming their e-mail service but let a group of people throw some pocket change at a video game console that isn't backed by a multi-billion dollar corporation and all hell breaks loose. I hope the Ouya succeeds if for no other reason than for the haters to have to wipe the egg from their faces. But who am I kidding? They'll just find some other underdog to kick.

<comment><USER4> As an entrepenuer, I'd LOVE to have people complaining about my idea.

For various reasons:

1) The idea hasnt come to fruition yet, so it can be shaped and molded with feedback. (unlike color or cuil which both hard-launched with a full product and strategy and no sense of reality)

2) People are talking about your company. peroid. Building something that noone cares about or only gets the odd "thats cool" is way worse than having pages of critiscm.

3) Knowledgable people are spending their time analyzing every part of your business. For free.

Once you get past the sensitivity to rejection/bad feedback which all entrepreneurs do in the first year, its not such a bad thing. Although obviously not a goal one should strive for.

</comment></comment></comment></comment></comment><comment><USER6> The Final Fantasy III remake port (as in III by the japanese numbering, not american III which was VI) has been out for awhile already on Android. It really works pretty decently for being on a phone/tablet, I recommend checking it out if you can stomach $15.99:

[https://play.google.com/store/apps/details?id=com.square_eni...](https://play.google.com/store/apps/details?id=com.square_enix.android_googleplay.FFIII_GP)

The game is a port of the DS remake to begin with, I doubt "coming to Ouya" is much more work than maybe adding controller support to the Android build.

It looks like SquareEnix just released FFI also.

<comment><USER6> Now that I'm more awake and reread the Ouya post, it goes to great effort to mislead which is pretty par for them. It really tries to imply that it's being released specifically for Ouya with "partnering with Square Enix to bring you", " first time gamers outside of Japan can play FFIII", "Previously unreleased in the U.S.", etc.

<comment><USER7> To be fair they had qualifiers like "on the TV"

<comment><USER6> Yep - stretching as far as they can to mislead without outright lying. I'm pretty certain if you didn't know that the game was already out on iOS/Android you would come away with the impression that this was some sort of exclusive deal with Ouya.

<comment><USER8> And... I suspect that this is the reason why so many people are very suspicious of the project; they seem desperate to mislead as much as possible, at every opportunity.

I understand that they want to drum up support and give a positive impression so that more people will join in, but a little more honesty I suspect would go a long way.

</comment></comment></comment></comment></comment><comment><USER9> I'm not exactly sure what they're saying here other than "Android games can run on our Android console".

<comment><USER10> They're saying "We got social proof from an A-lister"

<comment><USER11> FF3 is going to be coming to Android, Ouya or no.

<comment><USER12> It's already there on Android... [https://play.google.com/store/apps/details?id=com.square_eni...](https://play.google.com/store/apps/details?id=com.square_enix.android_googleplay.FFIII_GP&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5zcXVhcmVfZW5peC5hbmRyb2lkX2dvb2dsZXBsYXkuRkZJSUlfR1AiXQ.).

</comment></comment></comment></comment><comment><USER13> The console doesn't exist yet and SquareEnix already is already making FF- remakes for it! I'm happy to see a big name in the gaming business offering some support, but I'm more excited to see some original, thinking-out-of-the- box homebrew games. I want to play the next Cave Story; I've already played FF3 like a bazillion times.

<comment><USER14> FFIII was an NES game. One presumes the "remake" is just running the original ROM in an emulator. So the "development work" involved is essentially just getting a license written up and signed. Maybe they'll update some copyrights and artwork, too.

<comment><USER6> Nope. It was done as a pretty thorough remake for the DS a few years ago - added 3D, changes to core gameplay (that were not very well implemented as someone else pointed out), etc. These DS versions are what have been ported to iOS and Android.

</comment></comment></comment><comment><USER15> I haven't been following Ouya since the initial hype, but wasn't one of their initial talking points that they would only allow free games?

I guess they're doing paid games now: "But that's not the end of it: We're promising to deliver Final Fantasy III like you've never seen it before – Hironobu Sakaguchi's third installment in the role playing game franchise will be updated to exploit OUYA's high-definition resolution in glorious graphic detail. For those of you who are new to Final Fantasy, we'll offer a free demo so you can give it a go!"

<comment> aaron-lebo I believe the game either has to be free to play or have a free demo. So that requirement is easily fulfilled.

</comment></comment><comment><USER16> To be honest I couldn't care less about Onlive nor FF, I would like them to focus more on either hardware such as Wifi, more Ram or an SD card port or on useful software: Mame port or some useful license like GGPO (that could really enable an xbox live like experience on arcade games). I'm a backer but probably not their main usual target I guess, I'm more looking at it like a Rasberry Pi alternative than a real gaming console.

<comment><USER17> I still don't understand this craving for more RAM. Does Android need that much RAM for a single game? Does iOS? Does Xbox360? The games for OUYA will not be more powerful than that. And don't expect to keep the 1st gen of OUYA for 7 years, if you really care about gaming on OUYA. OUYA is more like a smartphone - something you buy once every 1-2 years, with much improved graphics performance.

ARM graphics performance improves 2x every 12 months, so 4x after 2 years. In fact I wouldn't be surprised if Tegra 4 brings that much improvement alone over Tegra 3, since Tegra 3 was a pretty small chip compared to competition, even at 40nm (therefore weaker), and Tegra 4 is rumored to have 64 cores (5.3x more than Tegra 3). I would much rather like it to come with Tegra 4 or some other 2013-ready CPU/GPU than more RAM.

<comment><USER18> If you read interviews and/or talk to people in the industry, they would tell you that more RAM expands the possibilities for many of the games.

Even for AAA titles like Battlefield 3, the difference in 64 players in a pc to 24 players on consoles according to the developers, was mostly because of the lack of memory.

1GB is huge for a game console. Just for comparison the PlayStation 3 has 256 MB of XDR DRAM main memory and 256 MB of GDDR3 video memory for the RSX.

<comment><USER17> But the games on Android and iOS are limited to like 50 MB each. Why would you need more than 20x that RAM for a single game that will look pretty much the same as what you'll see on tablets and phones.

<comment><USER18> textures

</comment></comment></comment></comment></comment><comment><USER19> Perception is reality. To the geeks this is "just android in a box" to everyone else this is a gaming platform that comes with a lot of games for free and is dirt cheap.

People seem to have forgotten on of the major reasons why the PS1 became so successful.

It wasn't it's superior hardware or software or numbers of colors. It was the simple fact that it could be modded and thus allowed you to play games for free.

<comment><USER20> >> To the geeks this is "just android in a box" to everyone else this is a gaming platform that comes with a lot of games for free and is dirt cheap

I personally like Ouya, but realistically, the second part of your sentence should be "to everyone else this is a gaming platform that they haven't heard of". Only the nerds really know about Ouya, Joe Q. Public probably won't hear about it unless the nerds who bought the first wave can make it go viral.

<comment><USER19> Never underestimate the next generations need for finding their pet pevee. They know more about what is going on than you might think :)

</comment></comment></comment><comment><USER21> Call me disenchanted, but Square ports to iOS have been little more than bald, lazy attempts to cash in on years-old, sometimes decade-old properties. And I'm not talking about the original games, I'm talking about the _ports_ (usually for PS1/2/X and Nintendo handhelds) being 10+ years old. Virtually every Square iOS port so far has dismal controls and little thought given to adapting to touch-based conventions...Making Retina-optimized text is about the biggest adaptation they've managed.

For these properties, they charge premium-based prices. For iOS, they don't make them universal...which as a business decision is fine, if unpopular. But they delay the iPad versions for months for inexplicable reasons, but I guess there will be fans who'll pay another $10+ for the new version.

So I don't think the porting of FF3, widely considered one of the worst of the early Final Fantasies, to be much more than another cash-in by Square.

* as cdr noted, the language to market this Ouya port is a bit hyped and misleading: <http://news.ycombinator.com/item?id=4317397>

<comment><USER22> The remake on the DS was interesting for the fact that they actually put quite a bit of work into it. I was happy to buy it because it looked and felt like a native DS game (full 3D graphics, new audio, etc). The Final Fantasy on my phone however, doesn't feel native. And they want $10 for it. No thanks.

<comment><USER23> The Final Fantasy III remake for DS felt lazy and suffered from lots of poor design choices. As an example, the remake changed the availability of certain classes, but did not change vendors' inventory, so you would run into situations where the equipment available from vendors didn't match what classes were available to you. Also, the class system lacked any semblance of balance with regards to level-ups; the only stat that was permanently raised when leveling up was HP, meaning that it was _always_ best to level-up as whatever class had the best HP growths. Furthermore, HP growths at level-up were based on a percentage of your existing HP, so if a character spent the first half of the game leveling as a low-HP class, their HP penalty would haunt them for the entire game.

I can't directly disagree with your statement that they "actually put quite a bit of work into it," because they did produce new 3D assets, which is a non- trivial task, and the localization had to be done from scratch since it was the first time Final Fantasy III had ever been released outside Japan. However, it certainly didn't _feel_ like a game that that got a lot of tender loving care; it felt like a cash grab predicated on the assumption that people would buy anything tied to the Final Fantasy brand.

</comment></comment></comment><comment><USER24> I'd assume that Ouya would get (S)NES emulators fairly quickly, if it manages to launch successfully.

</comment><comment><USER25> FF3? I thought FF7 was the one widely regarded as a classic?

<comment><USER26> Believe it or not the series contains more than one "classic" game. You're right that FF7 is the most popular though; presumably they went with FF3 for its lower performance requirements.

<comment><USER27> Highly unlikely the performance reqs between the two (specifically the DS/iOS/Android remake of FFIII vs. the PS1 FFVII) is that wide; Tegra 3 and similar chipsets are definitely capable of eclipsing both. But they already have a FFIII port mostly ready to go; FFVII has yet to be ported to anything besides PS1 and Win9x. And in true Sq fashion, they seem to be saving a FFVII remake for whenever they think they can extract the most cash from it.

<comment><USER18> According to their CEO, making FFVII is admiting defeat and that they will not be able to make a better game.

They will only release a remake when:

A) The money is needed/correct B) They make a better game in their view. With I suppose, overwhelming success.</comment></comment></comment></comment>


7-Eleven Struck Back Against an Owner Who Took a Day Off - <AUTHOR> https://www.nytimes.com/2020/01/06/business/7-eleven-japan.html <comment><USER2> This would be fine if he was running a store without the 7-11 name/brand.

As a business owner, I do empathize with him. He wants to be his own boss and make his own hours, but he still needs to keep his commitment or he needs to dissolve it the right way.

As a customer - this would be piss me off so much. There is a 24 hour fitness that I used to go to that closed at 10 pm. HOW IS THAT OKAY?? (this was years ago and still gets me worked up) This is just like that - he wants all the advantages of the franchise but isn't willing to uphold their brand. What's next? He doesn't like the coffee they source because he thinks it is too strong so he waters it down??

<comment><USER3> Uh 7-11's name came from the fact it was open from 7am to 11pm originally, so being open 24 hr/day is not an inherent promise of the brand.

<comment><USER4> You are absolutely right (1) and I have no idea why people down vote you, even if they think its irrelevant.

We, here at our office desks, are quick to demand that this store or that service is open 24/7.

The guy needed a day off. Go somewhere else and get your chocolate bar.

1: [https://en.wikipedia.org/wiki/7-Eleven](https://en.wikipedia.org/wiki/7-Eleven)

<comment><USER2> Yes, as a customer I like the same experience when I go from one chain to another - that's the value of their brand.

If he wants a day off then he should take a day off - I don't think 7-11 is setting his working hours or vacation days, but they do expect him to manage his store the way he's agreed to.

</comment></comment></comment></comment><comment><USER5> Shame on the New York Times for such a bs title.

They care that he closed the store not that he took the day off.

"Man loses franchising rights after violating core aspect of the franchise brand" doesn't have the same ring to it I guess.

<comment><USER6> Shame on you for not reading the article.

The entire point was that as a small franchise owner he has to work 24/7 on the clock every day of the week due to the company off-loading all of the risk and issues onto the owner. You don't see a problem with a company mandating that their employees work every single hour of every single day?

<comment><USER5> >The entire point was that as a small franchise owner he has to work 24/7 on the clock every day of the week

That's not the entire point of being a small franchise owner at all. He is allowed to have and has employees. He is supposed to run a schedule of them to keep the business staffed around the clock. That doesn't mean he has to personally be there for every single hour that it's open! How absurd.

>off-loading all of the risk and issues onto the owner.

There is no offloading of all risk and issues to the business owner. All risk and issues are already inherently the owners. That's what it means to be a business owner. It's how they earn their share of the venture. If things work out you can earn a lot more money than as an employee. If things don't then you crash and burn. That's what you signed up for when you created or bought a business.

>You don't see a problem with a company mandating that their employees work every single hour of every single day?

Sure I do. That's in no way what happened here though. He isn't the employee of 7 Eleven. He is a business owner who has leased their brand in exchange for agreeing to certain terms. He gets more customers because people trust that his business, as a 7 Eleven, will be open all of the time and in exchange he has to be open all of the time. And again, they don't want him personally there 24/7\. Just his business open.

<comment><USER7> _> He is allowed to have and has employees._

An article that was posted to HN last year [1] profiled several convenience store franchise holders who, it sounded like, weren't making enough money to afford employees.

After all, if your country has 1.5 jobs per job seeker, raising wages; and you're only making $20 an hour of sales on the overnight shift, you're going to be losing money on that shift.

Of course, you might argue that a business that marginal should just close down - but if you spent $$$$ setting up, stocking and advertising the store, which might have seemed a good investment before another store opened nearby cutting into your sales, the decision to close down might not be an easy one.

It also says that 7-11 has an "area-dominant strategy" where, essentially, having a high density of franchise stores is their business strategy. That's in contrast to many franchises that include an area of exclusive territory, so there's one successful franchise rather than two struggling ones.

[1] [https://www.japantimes.co.jp/news/2019/05/27/national/behind...](https://www.japantimes.co.jp/news/2019/05/27/national/behind- scenes-24-7-service-realities-owning-japanese-convenience-store/)

<comment><USER8> > the decision to close down might not be an easy one.

So what, we should adjust the laws, break the contracts and make everyone else jump hoops around him and give him special treatment because he has to make a difficult decision? This is not kindergarten, this is business.

</comment></comment></comment></comment></comment><comment><USER9> > _He said that 7-Eleven had offered to pay for his remaining inventory — > owners are responsible for buying their own products from the company at > wholesale prices_

This feels like an American MLM scam, just tuned to be actually profitable for the "owner" under normal conditions and therefore sustainable.

(Is this normal for legitimate American etc. franchises too, or is this specific to Japan's setup?)

<comment><USER10> Not really the same thing, but I used to work for a small food business that sold bottled/canned drinks from a fridge via a contract with Frucor (New Zealand), and the prices they charged wholesale to this small business were often _higher_ than what you could buy the drinks for retail at nearby supermarkets.

<comment><USER11> Would it have been illegal to buy and resell stock from the supermarkets?

<comment><USER12> No, but it's usually against the agreement you have with the supplier, which will, like this story, probably end with a terminated agreement.

Depending on your local laws, the nearby supermarket might have been selling below cost, so it might not be as huge a pricing discrepancy as you imagine.

</comment></comment></comment></comment><comment><USER13> Aren't there a crazy number of convenience stores everywhere in Japan, and where not, there are vending machines?

Also, I find something incredibly cozy about my city going to sleep at night. Almost nothing is open, not even most convenience stores, and I just find that so cozy.

<comment><USER14> I'm the opposite. I like knowing that at 3am there's somewhere that's open where I can buy things like contact lens fluid, pain relievers, etc. (7-Eleven happens to have those)

<comment><USER15> Perhaps just plan ahead for your contact lens solution. I get that it's convenient, but working those shifts is miserable (I did it).

<comment><USER14> I'm an imperfect human being. I'm going to go through contact lens solution and put off replacing it until I squeeze the bottle late at night and nothing comes out. I'm glad there are people I can pay at any time of the day to fix my self-inflicted problem.

<comment><USER15> Sure, but it's not great fun for the person on the other side of the counter.

<comment><USER16> Most people don't work for fun.

<comment><USER15> I imagine you understood what I meant by "not fun", but ok. I suppose my view is, if you can't plan ahead for your trivial purchases, I don't really care. I'd rather just shut the store down and let you bemoan the fact that you can't buy snacks and Tylenol at 3am.

<comment><USER17> Reach outside of your bubble and realise there are likely tens of thousands of people in your city who live a different schedule to you, for work and other needs like care and support.

There is room for a night time economy based around the people and services that run while you sleep in your standard schedule. Big cities wouldn't be possible without the efforts of people on AM heavy schedules.

<comment><USER18> Also not to forget, if there are people awake at night without outside pressure, then there's probably people fine with working at night.

In Germany you can't work on Sundays. I always wanted to work on Sundays as a student, Fridays and Saturdays were worse, since that's the only days where most social gatherings happen.

On the news I hear people saying they don't want to force people to work on Sundays. I'm thinking maybe, just maybe, not everybody is the same.

I even agree we need limits. But how about limiting it to working 5 days a week, instead of picking an arbitrary day where you can't work.

<comment><USER19> Germany is a very catholic heavy country, it's hard to do anything except church on sundays. Or fleamarkets on the now completely deserted shopping mall parking areas... Think an IKEA parking space completely empty on a sunday. They fill it up with flea markets instead :-)

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER20> I don't get it, if he doesn't like 7-eleven franchise conditions, why he just doesn't open regular non-franchise convenience store? it's not like they have monopoly, article claims they have 40% of market, so he would join majority of other convenience store owners

<comment><USER21> Because 7/11 handles all the products and logistics to deliver items multiple times daily. Where would he get things to sell, and how would they get to his store?

<comment><USER5> Wholesalers. The same way the other 60% of stores get things delivered.

</comment></comment></comment><comment><USER22> > Government figures show overwork was blamed for 246 claims related to > hospitalization or death in 2018. The retail industry was one of the biggest > sources, officials show. Another 568 workers took their own lives over job- > related exhaustion.

I find it mind blowing, and pretty damning of the culture of shame in Japan that the number of work related suicides is more than double the amount of work related hospitalizations. How doesn't this get more attention?

</comment><comment><USER23> Prior to World War II, Japan had massive syndicalist groups and labor unions that caused enough disruption to win universal male enfranchisement. Now, they have "black companies" working people to death with near impunity, while online mobs of right-wingers celebrate their behavior. Quite a horrifying trajectory.

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

<comment><USER24> How do you define "universal male enfranchisement" and how do you prove that claim?

<comment><USER25> [https://en.wikipedia.org/wiki/General_Election_Law](https://en.wikipedia.org/wiki/General_Election_Law)

</comment></comment></comment><comment><USER26> The other side of a culture of extreme duty is a culture of extreme shame. Its not the way for humans to live. We haven't yet seen the end of its self propagation.

<comment><USER27> Tying this to Japan when 7-11 runs a virtually identical model in Thailand seems weird.

<comment><USER26> Thailand is a relatively poor country where labor is super easy to find.

<comment><USER5> Australia is one of the richest countries in the world and our 7 Elevens are 24/7\. Along with many other businesses. There's nothing weird here. Have you never been to a city?</comment></comment></comment></comment>


Git-based issue management - <AUTHOR> https://github.com/dspinellis/gi <comment><USER2> So, it's something like TicGit? [https://github.com/jeffWelling/ticgit/](https://github.com/jeffWelling/ticgit/)

</comment><comment><USER3> Very cool.

s/loosing/losing/ Not a big deal, but it may as well be right. :)

I can see this being used in a smallish shop without "outside" stakeholders. But not in a large org with lots of smart but non-development stakeholders, like say clinical specialists or biologists in a medical device company.</comment>


Six reasons the Jedi could be villains - <AUTHOR> http://screenrant.com/star-wars-villains-jedi-sith-history/

<comment><AUTHOR> I watched "Revenge of the Sith" last weekend with the kids and they were quick to blame the Jedi for Anakin´s fate. In adult terms, they suggested that Darth Sidious did a proper mentoring and that Jedi mostly ignored him.

This article goes along this line.

Yes, yes .. a little freaky, I know.</comment>