Why I'm not leaving Python for Go - <AUTHOR> http://uberpython.wordpress.com/2012/09/23/why-im-not-leaving-python-for-go/ <comment><USER5> I'm not in love with this aspect of Go either, and I also find that the idiom for dealing with it (multiple return values and multi-statement if conditional clauses) doesn't play well with Go's scoping rules, so that I find myself regularly having to decide between cleaner conditional or an explicit variable declaration. I also don't love how it makes my code look like my teenage-years C code.

But I also think this is a very silly reason to adopt or not adopt a tool. No other approach to error handling is less fraught.

If Python is your only language, Go or something like Go is probably a very useful thing to have in your back pocket: compiled native binaries, fine- grained control over memory layout, and a simple and effective concurrency model is a good thing to have in one package.

There are a lot of things that annoy me about Go (and for that matter Python, which irritates me for very similar reasons). What I tell myself to get over that and keep an open mind is, Go may not be my idea of an elegant language (yet; I'm still learning to appreciate it), but it is an excellent tool. I can get over the language stuff if the tool works well enough, and Go seems to for me.

Incidentally, who "leaves" a language? I have a very hard time seeing how, even from the label on the tin, anyone could believe Go is a great solution for _every_ problem. Python sure as hell isn't either.

<comment><USER6> > No other approach to error handling is less fraught.

The thing that kills me about Go's error handling is you return error AND value all the time. It's like an Either that always has Left and Right. I think it's a bummer, especially coming from a group that has developed languages in the past.

<comment><USER7> I imagine that this is to keep compatibility with C. And also, this ensures that when a Left value is accidentally read as a Right one, you don't get a "random" bit pattern due to type punning, but a correct (albeit meaningless) value such as NULL.

<comment><USER6> I'm not sure how, C doesn't have multiple return values either. I also don't really understand the second part. How is that any worse than the current situation of not checking the error side and reading an undefined (or whatever it is?) value?

<comment><USER7> Well, the choice is between structures or tagged unions.

I'm not a Go user, but if I understand correctly ("It's like an Either that always has Left and Right."), functions return a structure with both an error code and a value.

To wrap a C function into a Go function with this signature, you can initialize a structure with { code: success; value:f() }; and then of course error checking has to be done C-style (errno, lib_last_error(), etc).

The problem with tagged unions is that when you access the wrong field (when it's not enforced by the language), everything can happen : you can build ill- formed values, jump to random places, etc. Having an explicit NULL in that cases is better.

In a nutshell, unsafe tagged unions < explicit NULLs < safe tagged unions.

<comment><USER8> Go actually returns true multiple values, not a structure. You can't assign it to a single variable, for example, you actually have to assign it to N variables, with N being the number of values the function returns.

</comment></comment></comment></comment></comment></comment><comment><USER9> I have mixed feelings about errors as return codes. Then again, I have mixed feelings about exceptions.

There are two general use cases for exceptions:

1\. Unexpected (typically fatal) problems;

2\. As an alternative to multiple return values.

(1) is things like out of memory errors. (2) is things like you're trying to parse a user input into a number and it fails. I despise (2) for exceptions. It means writing code like:

        try:
          f = float(someText)
        catch ValueError:
          # I just parsed you, this is crazy,
          # here's an exception, throw it maybe?

where this gets particularly irritating is when you start writing code like this:

        try:
          doSomething()
        catch ValueError:
          pass

I nearly always end up writing wrapper functions around that crap.

Java is worse for this because some libraries (including standard ones) abuse checked exceptions for this. I actually prefer:

        if f, err := strconv.ParseFloat(text); err != nil {
          // do something
        }

or even:

        f, _ := strconv.ParseFloat(text);

for this kind of scenario.

For the truly bad--typically fatal--error conditions and cleanup, IMHO defer/panic actually works quite well. I certainly prefer this:

        f := File.Open('foo')
        defer f.Close()
        // do stuff

to:

        try:
          f = open('foo')
          # do stuff
        finally:
          if f:
            f.close()

as Go puts the two relevant things together.

Don't get me wrong: I like Python too but I do think Go has a lot going for it and has a bright future.

<comment><USER10> >try: >> f = float(someText) >> catch ValueError: >> # I just parsed you, this is crazy, >> # here's an exception, throw it maybe?

No, you have it exactly backwards. It's with _return values_ that you have to check after every call to be safe. With exceptions you can truly say: if I don't know what to do if this fails then I don't do anything. You can let the exception bubble up higher, all the way up to crashing the program if you like (which gives a nice stack trace that can then be debugged).

With return values, if you don't check then you could be building up more and more trash and you won't even know it until you either hit a point of code that finally does look at what's returned, or if an exception occurs (e.g. segfault).

<comment><USER11> "Not checking" is just shorthand for pythons " except: pass".

<comment><USER12> But not checking is invisible. I can't grep for it. It doesn't stand out in a code review. It's almost never what I meant to do, so it shouldn't have been the default or easily overlooked, much less both.

</comment></comment></comment></comment><comment><USER13> If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex.

If you use exception handling, then suddenly catching errors becomes much easier, and writing code is faster, but it's not like your program is any more robust. If you catch an error up at the top, your program or function is probably just going to quit. Of course, you can add more code to deal individually with each of the exceptions in more robust ways, even to the point of wrapping each statement in its own try/catch block, but then it's no different in practice from returning error codes.

In the end, I just don't see much of a practical difference. In both cases, if you want to be a lazy or rapid programmer, errors will lead to your software just not working. And if you want to be conscientious about your errors, then you can do that in both cases.

Exception handling lets you handle errors "at a distance". It's convenient, but harder to keep track of. Returning errors keeps your code execution where you can see it, and you always know where it is. It's simpler, but more verbose.

<comment><USER14> I would guess that most (99%) of C programmers are lazy or has an rapid programming style then. Its a rare thing to see C source code that even do the simple thing like wrapping every write/read/print call with a loop that detects eintr. In my years of programming, I have yet to stumble on a other programer who even knows that one should be doing this.

Looking at c libraries and their example code, almost every time, the example lacks error handling. Its almost like people avoid doing error checking in C code because of the cumbersome amount needed to be done in order to check each and every time. If an example code would include error checking, the number of lines can easy increase 3-4 times the original size.

<comment><USER15> In Go if you use the return value of a function you must also assign the error to something, either a variable or explicitly ignore it by assigning it to _. It was designed this way specifically to avoid the problem of not checking error conditions in C code.

<comment><USER16> This breaks down when the method you call has no return value other than an error. In that case it is easy to forget.

</comment></comment></comment></comment><comment><USER17> Heh, I thought the answer was "Because my blog is named uberpython and it would be way confusing." :-)

But error handling is one of those topics that really gets people going. From ABEND in the old IBM batch days, to uncatchable signals like SEGV in unix and uncaught exceptions in C++ or Java.

I tend to come down on the "decide what you are going to do in the code, right where the error occurs" flavor of the argument. So checking for errors when they occur is important to me, what to do next gets to be sticky.

So there are three things you want to do:

1) Easy - you just want to quit/die/exit pretend you never existed. This is pretty easy and most OS'es and embedded toolkits have something along the lines of 'exit' or 'exit_with_dump.' So that later you can try to reconstruct what happened.

2) Is "this is bad, but it might be ok later" where you want to unwind to the point where this started but not completely exit. Exceptions are pretty good for this if used well since you can catch them at the 'unwind' point and if you can attach the unwinding actions (closing files, freeing memory, etc) to the return stack then it can be managable.

3) You want to plod along in a degraded mode, which means you need some way of communicating with the rest of your code that you're damaged goods at some level.

Go has an interesting mix which I haven't used extensively but I wouldn't dismiss it out of hand. The folks writing it run services that continue through partial outages so if it were too egregious folks would rebel inside of Google.

<comment><USER18> The problem I found is #1 is hard. In C# if I want to just exit/return an HTTP error I ignore the exception and it happens. In Go for the majority of cases I have to check the error and call a panic function. I wrote a helper function to do this - it takes one parameter and panics if not nil.

2 and 3 I've found to be at little less verbose as there's no try {...} catch{...} around it.

It seems a nice way of avoiding the stack sentinels or setjmp/longjmp that C++ has, which means the output is less architecture dependent.

Personally I don't think Go is quite ready for prime time, but it's definitely promising. I'm doing a couple of projects with it to see how it runs.

<comment><USER19> Have you seen the Error function in the HTTP package? <http://golang.org/pkg/net/http/#Error>

</comment></comment></comment><comment><USER20> It's not "tempting to ignore errors". You're the programmer, if you want to ignore it, do so. I don't know why you'd want to ignore the returned value and possible error on a GET request - given that 1) it can fail for so many reasons, and 2) the suggestion that you might be "GETTING" something. Ignoring the error of a print statement is more acceptable since it's unlikely to occur and there's rarely a lot you can do about it anyway.

Error handling is explicit, like the quote you quoted said it should be. If you ignore the returns (either explicitly or implicitly) you pay the price in debugging.

"leaving me confused as to which error happens when" Panics happen when something very bad happens. You shouldn't be accessing off the end of an array, it signals that you've probably programmed it incorrectly, rather than it being a problem with your input (~ish). Same with divide-by-zero and type assertions. However, they provide another control path that in a limited number of situations, can give elegant results.

<comment><USER21> That's his whole point. He _doesn't_ want to ignore errors but feels like Go is so verbose about it that it's a pain for programmers to deal with it. Example in case, _print_. Would you check its return value every time you call it? No.

Contrast that to other languages, such as python, where you don't _ignore_ the errors because _you know_ that if something goes wrong, an exception will be raised.

It lets you do stuff like:

def whatever(request): my_int = int(request.POST['some-param'])

Note that, in that case, we don't check if 'some-param' is in POST. Neither what happens if it's not a number.. Basically, an exception will be raised and a 404 will be shown.

<comment><USER22> It's actually worse than that. The blog has error handling code like:

        if err := datastore.Get(c, key, record); err != nil {
            return &appError{err, "Record not found", 404}
        }

This is pretty typical Google Go error handling, where errors are only actually used as boolean flags. Errors are universally returned as type 'error' so to actually do anything with the error you have to first cast it to some specific type. But that type isn't part of the method signature so you have to dig around in the source or, if you are very lucky, it was documented someplace. You end up having actual error handling plus even more error handling for if you got the error type wrong.

For instance if datastore could return 'record not found' or 'io error' then they would usually be treated the same way by the code because to do otherwise would be even that more of a hassle.

<comment><USER23> I guess you are super lucky: [https://developers.google.com/appengine/docs/go/datastore/re...](https://developers.google.com/appengine/docs/go/datastore/reference#variables) or even [https://developers.google.com/appengine/docs/go/datastore/re...](https://developers.google.com/appengine/docs/go/datastore/reference#Get)

      err := datastore.Get(c, key, record)
      if err == ErrNoSuchEntity {
          // entity not found
          return
      } else if err != nil {
          // some other error
          return
      }

Don't really see the hassle you are referring to.

<comment><USER22> I think this is exactly the point. You have to read the comment to get the error types (isn't compiler accessible), it doesn't list what all the possible error types are (doesn't say the ones documented are exhaustive), and the code returns a singleton error (no state) presumably so the caller doesn't have to do a bunch of casts..

<comment><USER23> > You have to read the comment to get the error types (isn't compiler > accessible), it doesn't list what all the possible error types are (doesn't > say the ones documented are exhaustive)

You're absolutely right. People should be able to use libraries without reading their documentation, and instead rely on compile failures to slowly iterate their code towards perfection. /s

Seriously, though, I believe expecting programmers to read documentation of a library they're using is a pretty low bar.

Also, no it doesn't list what all the possible error types are. To do this would require what amounts to checked exceptions in Java. The issues with these are relatively well known.

First, it complicates versioning as adding a new error type is a breaking change for all clients. When they get an error from an API, most clients either return that error verbatim, decorate that error slightly and return the decorated error, or handle a few specific error situations and return an error in all other cases. Declaring all possible error types makes your programs brittle, as it is easy for libraries you are using to break your code.

Second, they are a hassle for larger programs that touch many systems. It is easy to declare that you return an EntityNotFound error. But it is not so easy to declare that you return an EntityNotFound, MemcacheCASConflict, FileNotFound, FileExists, PermissionDenied, Timeout, InvalidJSON, ConnectionClosed, or TemplateRenderingFailed error. This is perfectly reasonable set of errors for a simple method that gets a value from datastore (possible caching it) decoding a field as json, and writing a template to an HTTP connection. Any 'simple' wrapper of this method then inherits all of these declarations. Now certainly with Java, IDEs will "fill in all the forms" for you, so this problem is a little more palatable, but Go does not require programmers to use (often heavyweight) tools to make them productive.

> code returns a singleton error (no state) presumably so the caller doesn't > have to do a bunch of casts

This is a little disingenuous, as you don't really know why they made it a singleton error. I can't think of any state that would be useful in this situation, can you?

The Java version of this API throws an exception with a single field, the Key that could not be found. I think this is supremely unhelpful and just adds clutter to the documentation, as the user of this method clearly already has this information in hand.

</comment></comment></comment></comment></comment></comment><comment><USER24> I suppose it's all a matter of taste. The error handling design decision is one thing I really like about Go. I write high reliability embedded software and "throw/catch" just doesn't cut it for me since it obscures possible error conditions thrown from subroutines. I want to have to explicitly deal with those errors whenever they might occur and error returns are a good way of doing that.

For every language feature someone likes there's someone else who hates it, and vice-versa.

<comment><USER25> I cant follow. Throw/Catch is as powerful as a error return value but it does not let you ignore errors without writing any code.

<comment><USER26> Unless they're unchecked exceptions, of course. In Python, all exceptions are unchecked.

The proliferation of checked exceptions all throughout the code is a whole other ball of wax.

<comment><USER25> Checked exception need to be handled properly. It depends on the sanity of the API. However, the standard way how to handle checked exception is a lot easier to maintain than error return values.

<comment><USER27> The only mainstream language that has checked exceptions is Java, and it is almost universally agreed, even within much of the Java programming community, that checked exceptions cause more problems than they solve.

Of course, unchecked exceptions have the problem that is basically impossible to keep track of what exceptions a function might throw (because it has to document all the exceptions that any functions it calls might throw too, and so on and on.)

In the end, of all error handling mechanisms around, Go is by far one of the best.

</comment></comment></comment></comment></comment><comment><USER28> I write Python and Go code every week, and have since I started using Go almost 2 years ago.

I appreciate Go because I'm working hard to become an engineer who builds robust software rather than a sloppy hacker that throws scripts together. One significant difference between the former and the latter is carefully handling errors versus not.

Python's error handling seems much more succinct only because most of us don't both handling errors at all! Every other line throws many exceptions, but we ignore this for convenience. (Those ugly "except ___:" statements ruin our oh- so-cool one-liners!)

Bottom line:

When I feel like having fun making something simple and getting it done _fast_, I use Python.

When I feel like building something that _needs_ to work -- especially anything that does more than one thing at a time, or should use all cores efficiently -- I use Go. And yes, that means taking error handling seriously.

</comment><comment><USER29> I don't understand why anyone would "leave" a language that was working well for them just because of some hype. Don't get me wrong, I think we should all be striving to learn new things, but that doesn't mean we should just drop everything to jump on the next bandwagon.

<comment><USER30> Your statement seems self-contradictory. Should we strive to learn new things, or should we not jump on the next bandwagon? Are you saying that we should try new things but not really try them very hard, or what?

There is such a thing as progress, and in my opinion the way you get it is by spending lots of time trying new things and seeing which ones work. So I'm in favor of "leaving a language that was working well for them just because of some hype."

<comment><USER31> Because hype != progress. Hype is basically a bag full of air.

You can _try_ new things, but abandon the other ones because of _hype_ (or thinking it's better cuz "ppl who don't know anything about languages said so") instead of true technical merit is pretty fucked up :)

Now then again Go ain't bad, but I don't see it being _better_ enough than Python to switch in this case. Python in better for many things as well. Not a large step enough.

<comment><USER30> Hype is a bunch of people claiming something is good. If there are enough people, you should probably go find out whether it really is good. If it really is, then _voila_! Progress happened. If it's not, you stop. This guy is busy finding out, that's all.

<comment><USER31> Fair enough, but I fear that most of the time hype comes from people who fear missing the latest boat, or who think it'll help them if they say stuff like XX is cool (a misplaced positive attitude always helps more, than misplaced criticism)

With mass globalization of the hype, we have countless examples of hype - <USER2> for programming - around things that aren't especially good.

Marketing people know that pretty well.

</comment></comment></comment></comment></comment><comment><USER32> Exceptions are like garbage collection.

Garbage collection relieves you from the drudgery, accounting and bureaucracy of manual memory management and indirectly leads to more expressive forms of programming once function boundaries are freed from having to specify who owns the data being passed back and forth. But you still need to be aware of space vs time usage, you still need to know where memory is being allocated, used and kept alive in your program, and you can still have "leaks" where a data structure is rooting too much dead data. This isn't immediately obvious to the novice, but that isn't IMHO a good reason to dislike the "magic" behaviour of GC. In the hands of someone who knows what's going on, programs get much simpler.

Exceptions relieve you from the drudgery, accounting and bureaucracy of manual error passing and recovery, and indirectly leads to more expressive forms of programming once function boundaries are freed from having to specify how rich error conditions are passed back along the chain of callers. But you still need to be aware of errors that require aborting and errors that can be fixed and resumed. You can still ignore exceptions that leads to programs crashing when they shouldn't. Looking at a program using exception handling, it sometimes isn't immediately obvious to the novice how the exception plumbing is working (especially since you don't usually see it at the function call level), but that isn't IMHO a good reason to dislike the "magic" behaviour of exceptions. In the hands of someone who knows what's going on, programs get much simpler.

<comment><USER33> >In the hands of someone who knows what's going on, programs get much simpler

I never really got this argument. With RAII types that have value semantics (ala shared_ptr) what is so difficult about memory management in C++? I guess there are reference cycles, but weak_ptr can help there. Manual ref-counting (like a COM AddRef/Release pattern) can be tricky, but that is where attention to detail, code reviews and basic competence come in. RAII wrappers with value semantics help here too. Most problems I have seen with that have been people simply not bothering to learn even the basics or using "smart" objects without understanding how they work or how to use them properly, which really isn't that hard, honestly.

>that isn't IMHO a good reason to dislike the "magic" behaviour of exceptions.

Agreed, my primary pain point around exceptions is people that write functions that mutate some state and are interrupted in the middle via an exception and stack unwind leaves objects in some franken-state. Transactional semantics in the face of exceptions don't just happen except in trivial cases (i.e. functions that don't mutate state or have trivial unwind semantics where they must only restore say a single mutated value).

That said the same problem exists anytime there is state mutation and multiple, failure exit paths. For some reason I guess the code I have seen using error code return style tends to handle this better. Could just be some kind of selection bias.

<comment><USER32> In my experience of web server apps, it's been fairly easy to guarantee that either the whole request succeeds, or - if there was an exception - <USER3> change is rolled back. Both user state and database state has been transactional, and state that lived on in memory in between requests was either read-only or caches.

In UI apps, it's much much harder to guarantee transactional semantics unless you're using persistent data structures or similar techniques that make in- memory transactions / undo trivial to make correct. So it makes more sense for exceptions there to save user data where possible, log the error (potentially back to the vendor), and restart the app.

(I don't want to talk about C++. I think both C++ exception handling and memory allocation are broken by C++'s design. You can only make it sort of work with coding standards, and even then it's labour intensive. If you don't yet understand why GC increases productivity, it's an epiphany you'll need to look forward to. Bonus: GC also makes exception safety far easier. For example, you can write a stack.pop() that returns the value popped - one of my favourite examples of C++ being broken.)

<comment><USER33> >If you don't yet understand why GC increases productivity, it's an epiphany you'll need to look forward to.

Oh I fully understand/agree with that, I just don't find C++ memory management to be too hard. The concurrency concerns pointed out by others are true, though. Whether they (the concerns) are offset by the lack of deterministic destruction and the extreme triviality of creating reference chains that root things far longer than needed due to the root being live while the rest of the chain should be dead, is another question.

As you pointed out, in some domains transactional code is fairly straightforward, or at least tractable without inducing massive depression. In some other domains, not so much :)

<comment><USER32> The domain of programs for which C++ memory management is not hard has only a partial intersection with programs that are small, expressive and easy to understand.

That is, if you take C++'s techniques for memory management for granted, simpler approaches to problems won't even occur to you.

</comment></comment></comment></comment></comment><comment><USER34> Rejecting something because it's "from the 1970s" seems like a particularly weak way to roll. Automatically equating "old" with "broken" is just as lazy as automatically equating "new" with "pointless".

The world is far more nuanced than that.

<comment><USER35> "Old" as in, the last time this seemed like a good idea was the 70's.

</comment></comment><comment><USER36> The author of the blog post is overlooking a major feature here. Go does multiple return types, so you can do things like this: i, err := getValue() however if you want to ignore a return variable or in this case the returned error you use an underscore like this (same as in haskell): i, _ := getValue()

This is Go's mechanism for handling (or ignoring errors) which imho is really nice because you don't have to learn anything extra, like throwing/catching error mechanisms

<comment><USER25> That's not the same as handling an error in a central spot automatically.

<comment><USER26> Handling errors in one spot doesn't work for all situations, though, right? Especially in an OO environment an object may need context for retrying a request, or some other kind of error decision making. So in practice some exceptions percolate through the object graph, while others are handled in- house, so to speak.

<comment><USER25> It works for most situations. If you need retry logic - exceptions is the wrong way to go. Errors returned by the standard library are most likely not errors you want to retry by default.

<comment><USER26> That depends, though, doesn't it? Just about anything network-related is subject to flakiness, disconnection, and timeouts. That means HTTP, database connections, sockets, etc.

</comment></comment></comment></comment></comment><comment><USER37> > Verbose and repetitive error handling

If you were to handle the same error cases in Python that you gave examples for in Go, it would probably be even more verbose with the try/catch wrapped around.

> Errors passing silently – ticking time bombs to go

Are you kidding? Unless exceptions are documented well, which they rarely are, this is a much greater problem when using exceptions.

<comment><USER25> > If you were to handle the same error cases in Python that you gave examples > for in Go, it would probably be even more verbose with the try/catch wrapped > around. Not sure what you are talking about:

try:

      datastore.Get(c, key, record);

      viewTemplate.Execute(w, record);

catch e:

      appError(e);

<comment><USER26> Is catching all exceptions really what you wanted to do here? A generic appError() is not equivalent to handling each possible failure more by type, as the Go example does.

<comment><USER25> My bad. Good point. I looked at what he meant - not what he wrote. :)

</comment></comment></comment></comment><comment><USER38> As usual in these threads about Go, I really wish people would consider Haskell as a nice alternative. A lot of people write Haskell off as "academic" or "impractical", which I feel is not an entirely fair assessment.

Particularly: Haskell is fast, concurrent by design (whatever that means, I'm sure Haskell is :P), typed but not cumbersome or ugly (less cumbersome and ugly than Go's types, even) and--most importantly for this article--does error handling really well.

In a certain sense, Haskell's main method for handling errors is actually similar to Go's. It returns a type corresponding to _either_ an error or a value (this type, naturally, is called Either). This method is special, oddly enough, because it _isn't_ special: Either is just a normal Haskell type so the error checking isn't baked into the language.

Coming from another language, you would expect to have to check your return value each time. That is, you fear your code would look like this pseudocode:

        if isError val1
          then pass val1
          else val2 <- someFunction val1
               if isError val2
               ...

However, this is not the case! The people implementing Either noticed that this was a very common case: _most_ of the time, you want to propagate an error value outwards and only do any work on a valid value. So you can actually just write code like this:

        do val1 <- someValue
           val2 <- someFunction val1
           val3 <- someFunction val2
           someFunction val3

then, if _any_ of the values return an error, it gets propagated to the end of the code. Then, when you want to check if you actually got a valid value-- maybe in some central location in your code, or wherever is convenient--you can just use a normal case analysis.

Additionally, while the errors _do_ pass through essentially silently, the type checker does ensure you deal with them at some point before using or returning them. If you ever want to get the Int from a Either Error Int, you have to either handle the error case somehow or explicitly ignore it (e.g. with a partial pattern match). The latter option will generate a compiler warning, so you can't do it by accident without being notified.

So the mechanism is simple, but it can also stay out of your way syntactically. So what else is this good for? Well, it's just a normal data type, nothing special; you can use existing library functions with these values. For example, you can use the alternation operator <|> to find the first non-error value:

        val1 <|> val2 <|> someFunction 5 <|> ...

This is often a very useful idiom which would be harder to write with a different way of handling errors. There are more utility functions like this (e.g. optional) that let you make your intents very clear at a high level. The optional function, for example, lets you do exactly what it claims: you can mark a value as "optional", meaning that any error from it will be ignored rather than propagated.

You can also layer on this error-handling logic on other similar effects. For example, there are some types (like LogicT) that represent backtracking search. Combining error-handling with nondeterminism gives you a question: should an error cause the _whole_ computation to fail, or only that particular branch? The beauty is that you can choose _either_ option: if you wrap LogicT with ErrorT (this is just like Either except it can be combined with other types) an error will cause the _whole_ computation to fail; if you wrap ErrorT with LogicT, the error will only cause the current branch to fail. This not only makes it easy to choose one or the other, but also makes it very clear which one you _did_ choose: it's right there in the type system in a very declarative fashion.

Haskell also has a bunch of other advantages which aren't worth going into here. I think anybody looking for something like Go--a fast, high-level, concise, typed alternative to Python--should _definitely_ consider Haskell. While it may not seem so at first, I believe that Go and Haskell are good for a very similar set of problems and so actually overlap quite a bit.

If you really dislike some particular things about Haskell, you should also consider some similar languages like OCaml and F#. I personally prefer Haskell, but there are definitely good cases to be made for either of the other two.

<comment><USER9> This kind of comment kinda misses the point.

Haskell (IMHO) won't ever be mainstream for much the same reasons Lisp never was (or will be?): it has an incredibly high learning curve (eg [1]).

This is really the problem of the "pure" functional languages. Functional programming is suited to some tasks. With others the fit is almost tortuous. Imperative programming is well-suited to how we think and how we break down tasks.

If you look at the popular languages they're pretty much all multi-paradigm (eg Ruby, Python, Go, C#, arguably even C++/Java) meaning they give you the low-hanging fruit of functional programming while still being in a relative sweet spot of being easy to learn yet reasonably expressive.

Why I think Go has a very bright future ahead of it is that it is the first of these multi-paradigm language to combine all these features:

\- easy to learn (seriously, go look at how short [2] is; you can knock that out in an afternoon);

\- it is minimal. I LOVE Go's minimal OO model for example; and

\- it is statically typed.

If you look at the other statically typed multi-paradigm languages you have C#, which is generally well-regarded... except (Mono notwithstanding) it is very Windows-centric. Java is, well, Java. C++ is _incredibly_ complicated.

The only thing Go is missing is a mode for (semi-)manual memory management. I'm thinking something like Obj-C's ARC (in iOS 5+) and it could well supplant C/C++ for the vast majority of their (already shriking) use cases... eventually (Go has some work to do on speed).

[1]: [http://stackoverflow.com/questions/377082/how-long-does- it-t...](http://stackoverflow.com/questions/377082/how-long-does-it-take-for- you-to-be-comfortable-with-haskell)

[2]: <http://www.miek.nl/projects/learninggo/>

<comment><USER39> This kind of comment kind of misses the point. The monadic style of threading error values is perfectly compatible with imperative programming if only language designers knew about it.

<comment><USER40> Problem is that you then have to explain monads to average programmers who'll be using the language.

I love monads (I love arrows more, but that's another issue). I'm a language design geek. My level of expertise is different from someone who has just been hired into a new job and wants to get things done.

I suspect that most language designers know about monads - I'm not sure Rob Pike did, but it's pretty common knowledge among folks who do this stuff. Until you can explain them to the folks who'll be using the language in a way that doesn't make them seem like arcane black magic, though, you'll find programmers will just say "I don't get this" and use what they're familiar with.

<comment><USER10> >Problem is that you then have to explain monads to average programmers who'll be using the language.

No you don't, this is exactly what you don't need to do. Do we explain the finer points of stream implementation to would-be C++ programmers? No, when they need to do something non-standard with a stream/monad, that's the time to talk about them. For the majority of programmers it's just "when you need to write to a file you do it like this".

<comment><USER41> The Either type described in the first comment is also a Monad. They are more important in Haskell than just "when you need to write to a file..." and I don't think you can totally grasp the error handling method without understanding them.

<comment><USER10> I couldn't disagree more. The Either type may have a Monad interface, but it's a Sum type and languages that don't have thousands of Monad tutorials also have Sum types. There's no need to explain Monad theory to someone just to explain Sum types or even why chaining do expressions doesn't do unnecessary computations in the face of errors. Just show them the code for join and >> and they'll see why it works. No need to bring up Monads.

</comment></comment></comment></comment></comment></comment></comment><comment><USER42> Of course there is a difference between an "index out of bounds" error and a network connection error: one is a programming error and the other is not.

</comment><comment><USER43> On the other hand, us who haved loved and embraced C don't mind this at all. It's up to us how to arrange the error handling.

Different situations warrant different strategies. Sometimes it's ok to return NULL, sometimes it's ok to return true/false and pass the actual result back indirectly, sometimes it's ok to return the value but use an external error flag. Sometimes it's ok to mix control flow and external flagging of errors, namely what an exception is, effectively.

However, in my opinion, languages who point too much to one single error handling mechanism are more irritating than languages that leave it up to the programmer. I'm particularly wary of exceptions per se: they're a really nice, clean concept but on the other hand I rarely hit an use case that would be a perfect hit for exceptions, and even those perfect cases for exception- handling wouldn't look too shabby if designed with other error handling strategies.

On the other hand, many cases where errors are handled with exceptions get awfully ugly in the normal case. For example, the "try: ... except <name-of- error>: pass" idiom in Python. I can't count the number of times I've written a small wrapper function around a trivial exception handling case, that just flattens the result and error into a suitable value if that fits my use case.

</comment><comment><USER14> When dealing with C and error handling, I have rather simple rule. If in the process of writing a simple program (+1k lines), and you did not find a bug in the libc documentation, then you are not looking hard enough at return values.

I do not have the same rule for python.

</comment><comment><USER44> I see both pros and cons in the Go approach.

I find Python's exceptions model to be something that _does_ occasionally frustrate me. For example, I'm used to using NSIS for some things (the PortableApps.com Launcher being one thing); its model is that a command may set the global error flag. This means that some sorts of things will fail silently - occasionally bad, but generally good. Some styles of Python scripts (generally automation scripts rather than full-blown programs) would do much better ignoring most errors. When you have a script merrily chugging along and all of a sudden due to some obscure corner case (perhaps not even documented) in a small, incidental part of the script the _whole thing_ quits, it can be rather annoying.

The Go approach lets you catch errors if you want, or drop them, much more easily than Python approach. My inclination at present is that the Go approach is more likely to end up with error-resilient code, as it encourages dealing with errors each time, while Python typically encourages you to let the caller deal with an exception if you can't - but often I think the caller doesn't realise that he should. Or after a couple of levels of indirection, it's not even documented that that exception can occur. (This sort of thing, I believe, is something that Java's checked exceptions were supposed to help with - either deal with the exception or declare it.)

For myself, I've had lots of experience with Python and am now dabbling with Go, using it for two smaller projects to decide which to use for my next major project. At the very least, I think the approach is worthwhile trying in a serious project that its merits and those of the Python approach may be more completely analysed.

</comment><comment><USER45> I'll agree that this is perhaps the single thing that I don't like about Go. Now, you can argue it helps with "explicit error handling" and all that, but in that case you might as well have must-be-caught exceptions.

Anyone want to fork Go?

<comment><USER46> Only if we call it Goto

<comment><USER40> Or perhaps GoTwo.

</comment></comment></comment><comment><USER23> Maybe its just me, but I like the fact that adding exponential backoff to an HTTP request goes from <http://play.golang.org/p/8WQ8XXrKw0> to <http://play.golang.org/p/3tCiNhAfo3>, in no small part due to the explicit error-handling style of Go.

</comment><comment><USER47> Psh, obviously trigger_doomsday_device will only respond to an http POST.

Once again the president has been saved, thanks to HTTP Pedantry.

<comment><USER48> > HTTP Pedantry

I propose a new HTTP verb, MEH, to address the belief that the HTTP verb mechanism is unnecessary or over specified. The semantics of HTTP MEH are application-defined, so it can be used to fetch, update, replace, query, delete, or whatever the application defines to be necessary. Services honoring HTTP MEH implicitly signal that interoperability is not supported, but that intermediate proxies 'should do the right thing' regardless.

</comment></comment><comment><USER49> On the topic of when to use error-returns vs. when to use panic:

I struggled with this aspect of Go coding too and what I decided was that, in order to choose your approach to errors, you should think about how important it is that your function can be composed into an expression:

        x := foo(a) + bar(b)

vs.

        c, err := foo(a)
        if err != nil {
            ...
        }
        d, err := bar(b)
        if err != nil {
            ...
        }
        x := c + d

It's a trade-off. By using "panic", you enable more concise and compositional code. By using error-returns, you are being more explicit and making it easier for the caller to handle errors at the call-site.

Usually, functions that can fail are not the kind you desperately want to use in expressions anyway. So error-returns are more common. But there are many situations where errors can happen and where composition is a big win. In those cases, you reach for "panic".

If you look at some of the built-ins that can panic--I'm thinking of array- indexing and division and regexp.MustCompile(), for example--you notice that these would become very cumbersome if they used error-returns instead.

There's also the issue of initialization. That's the justification given in the case of regexp.MustCompile(). An initializer must be a single expression.

The words "panic" and "error" probably lead people to think that you should make the decision based on severity but I don't think that's right.

(That's just my take on it. I'm no Go expert so there are likely better ways to think about it.)

<comment><USER26> As I understand it, it is about severity. I think "panic" and "error" are meant to handle situations where there _is_ no obvious, correct answer, like with array indexing. A nil pointer is another gimme example. Some languages have unchecked exceptions — maybe conceptualize it somewhat like that. panics() are for disasters, for serious program errors.

By contrast, a network timeout is not a disaster. It's not "normal" or desired behavior but it's well within widely-known modes of behavior.

Composition is nice-to-have but in general you ought to be able to write Go as if everything that does _not_ return errors will succeed under the vast majority of circumstances, or where failure is inevitable.

Recover is, among other things, a failsafe of sorts for cases when code you do not control (e.g. a library) panics. It might be catastrophic failure for the library, but it may not be for your code, and you need an escape hatch.

...I am not an expert, either, but I've spent a fair amount of time on the Go mailing lists. I feel like I'm actually repeating something I've read, but Effective Go doesn't talk much about this. (It does say that library functions should avoid panic.)

<comment><USER27> Panic() should only be used to signal either programmer error, or truly panic- worthy situations where state is so messed up that crashing is the only good option.

Put another way: when you call an API correctly, it should be safe to assume it will never panic().

Panic/recover can be used in rare occasions within libraries to do more exception-ish style error handling, but those panics should _never_ be allowed to escape and cross API boundaries.

</comment></comment></comment><comment><USER50> This kind of error handling is the best part of Go.

</comment><comment><USER51> >That problem is errors are handled in return values. 70′s style.

>This is one of the things I can't stand in C.

Having to check error values for every function call is indeed a pain. But C has macros and I think it is a nice and elegant way to handle errors. I personally prefer MACROS to exceptions when writing C/C++ code. But to each his own.

Does anyone know if go supports macros ? If they do not, it is one ugly problem to have!

 __EDIT __I just realized you can write custom exceptions that can provide similar information about line numbers, functions etc. So removed a line saying that was a plus for macros.

</comment><comment><USER52> I am eternally asking myself how do people handle exception in multi-threading programs ? Not that error code solve the issue at all, but it look easier (less complex) to handle thread error with error code

<comment><USER27> Well, given how hopeless it is to try to do threaded programming with Python, I guess that is not a consideration Python programmers usually worry about.

</comment></comment><comment><USER53> Out of curiousity: Aside from "returning errors" and "throwing exceptions", is there any interesting research into other ways of error handling?

<comment><USER54> Common Lisp has an interesting exception system where errors have a chance to be handled without unwindind the stack. Basically, functions also receive an "error handling" object as an extra argument and they consult when they encounter an exception. The error handling object then edcides wether to continue operation, or to unwind back.

<comment><USER55> > Common Lisp has an interesting exception system

Called "conditions", fwiw. Smalltalk has a very similar system (the main difference is in the declaration of restarts)

</comment></comment></comment><comment><USER56> Someone can fix this by creating and popularizing a simple preprocessor that implements a macro called "safely" that expands to something like "call this function, and then if it errors, report the error to STDERR and abort execution". Then just prefix the majority of your commands with "safely", and implement your own error-handling in the few cases where you care.

</comment><comment><USER57> What happens in Go if there is an exception (division by zero or whatnot)? Does it just exit, no stack trace? I am so used to exceptions that I don't even know how it used to work without them. I think getting a stack trace for debugging is really important...

<comment><USER58> You get a panic, which can be caught. <http://play.golang.org/p/IaTAGizhrF>

</comment></comment><comment><USER59> Personally I think the community might be spending too much time on Python 3.

Python 2 is fine, and the upgrade will offer few significant advantages for most people.

I think the effort would be better spent working on things like frameworks and tools for web development.

</comment><comment><USER60> My opinion: I'm not a fan of Python.

* It's really slow. * Most people write their code statically, but it's dynamically typed language anyway. * Things like '__init__'... what? * Having something you can see (whitespace) be significant is a bad idea. * Even worse, the community likes to use spaces instead of tabs, which makes the 'significant whitespace' a significant problem. * With the exception of Flask, important design patterns and lessons: DRY, SOC, DI, SRP, etc are largely ignored and called "Java-like."

Anyway, that's my $0.02

<comment><USER61> Sure, python is slow. For problems where this matters, there are usually python libraries available that will do it much faster than pure python (e.g. for scientific number crunching you use numpy, which is using FORTRAN behind the scenes). There are probably some problems where performance is critical and no libraries are available, but not many.

Sure, python is dynamic; at the time it was first created it was hard to provide the level of flexible ("duck") typing python has in a static environment. Now that typing has advanced, we are starting to see some level of type annotation support in python; I would expect it to get static typing eventually, but we can't break existing code. Still, I can totally understand leaving python for a static language with good type inference, like haskell or scala. I don't think go's type system is powerful or elegant enough though.

__init__ is fantastic; it removes all the special cases around constructors you see in other languages, and makes it "just another method" that follows all the usual method resolution rules etc. This means less to learn, less to bite you, and much easier to e.g. refactor a constructor into a factory method (or vice versa).

Whitespace isn't significant, indentation is. And when you look at a piece of code, you can see the indentation far more quickly and easily than you can see the braces. At least I can.

DRY, SOC, SRP are very much part of the python philosophy. I find python's standard library is much better at following "tell, don't ask" than most languages'. I agree that many python programs should follow the DI principle better and possibly the language should have better support for it, but IME the java/spring-approach as it's usually implemented doesn't really provide DI, it's just a complex reimplementation of singletons. I've yet to see a language or framework that can really help programmers do DI right if they don't already know.

</comment></comment><comment><USER62> The principle behind Go's design decision is based on actual experience and need to be understood by amateurs.

The idea is quite simple: _errors are not some rare special cases, they are ordinary, general events_.

That means there are no need to some special mechanism for handling them. They should be handled as ordinary events within common FSM.

There is no contradiction in using the general mechanism of examining returned values to determine the state of procedure execution.

Any FSM requires _if_ (or _cond_ ) statements. It is the essence of a program's logic.

The mechanism of exceptions was wrong. It is wrong in Java, it is wrong in C++. It is just a bad design.

The good design is using the same mechanism the underlying OS uses. In case of UNIX-derivatives it is the explicit checking of a return value. Because errors are common and ordinary events.

Amateurs believe that errors are rare, and they will avoid them. This is over- optimistic - in practice errors are of nothing special. It is just an alternative branch of a condition, where a consequent assumed to be a success.

</comment><comment><USER63> The error handling style is certainly different - but it's not so bad. It's a matter of style and getting used to stuff.

Maybe a better error handling mechanism is needed - but I'd prefer if it's not exception handling. Perhaps lisp style error handling? What ever that is - <USER4> I'm not familiar with it - but I keep hearing lispers brag about how awesome it is!

<comment><USER30> [http://www.gigamonkeys.com/book/beyond-exception-handling- co...](http://www.gigamonkeys.com/book/beyond-exception-handling-conditions- and-restarts.html)

Think exceptions, but instead of blowing away the stack on the way up to your exception handler, it gives you the option of resuming execution in some way where you left off. It also lets you encapsulate error handling better.

<comment><USER64> I am glad to see some CL condition system pop up here. This article basically turned me off from Go and reading peoples support for C style error handling has made me question what the heck they are thinking.

There are actually several nice things about the CL system, but nothing there is going to convince someone that actually thinks not only that having every return value in your language serve the role of an error signal is reasonable, but actually arguing that it is equivalent from a programmers perspective or even a better method of programming.

<comment><USER65> Instead of insulting people and declaring that you can't convince them, try posting some useful information about CL condition system and why you think it's better than everything else.

<comment><USER64> First let me apologize for the length, second I will say that to my knowledge none of this is about the CL condition system in particular, third this is basically a brain dump because I need to get back to work and still don't understand the error code camps points...

I definitely wasn't trying to insult but I recognize that I wasn't being helpful either. I was basically throwing up my hands. And while I like CL's system, I haven't come close to trying everything out there so I can't be a judge; I mean this not like a cop out but seriously, I am very poorly informed about what other languages have to offer.

But since you ask: I guess if I was trying to convince someone that exceptions are inherently a better mechanism, I would start by exploring how arithmetic is handled in the C language. Let's say we have a function called "add" that adds two numbers. Typically we would think expect that the return value of such a function should hold the result of that addition. It would be naive, however, to expect add to always complete without something like an error happening. While addition of two numbers seems safe, it isn't when we start using our imperfect number representations such as floating point numbers (susceptible to overflow, underflow, loss of precision, and more) but also with machine sized integers (susceptible to overflow) and even bigints (what happens if we attempt to add two numbers and exhaust system heap space?). The way these are currently handled in the C language (to the best of my knowledge) is by three different mechanisms: 1) floats return special floats that say indicate that there was an error somewhere, like NaN (though you can probably instruct your OS/hardware/whatever to issue these as signals instead of silently spitting out an NaN), 2) wrap-around is loosely taken as a standard but truly it has undefined consequences, your code must guarantee that this cannot happen, and 3) the program will probably exit. This is messy but we have learned to deal with it and has become second nature to C programmers; but that doesn't means it is good.

But this doesn't need to be the case, we could use the return value checking that is being promulgated by some here. We can define add as...

error_code add(int a, int b, int *return)

...where int could be any number type and translate every occurrence of "a+b" in our code into something like...

int ret; if (err = add(a,b,&ret)) { // err handling here } // ret holds the answer here

I cannot believe this is preferable to anybody, in fact I am going to go out on a limb and say that it isn't. Instead we just trust this to work when we know that there are instances where it won't and, in the case of floating point math, it is extremely common for you to hit those cases where it doesn't work. If we were serious about writing code that handled these errors gracefully, our C code would be unmaintainable. If we were honest about the source of this laziness, I think we would say that this is due to the syntactic and mental overhead of the error handling. The fact that we don't code like this, even the very fact that C will spit out an NaN and propagate it along indefinitely, is proof in point that people dislike this type of "check the return value" error handling. This is C more or less pushing us to write code that is less robust.

If we really wanted to consider what happens in a Common Lisp system, you would have a function "add" that takes two numbers and will always return the correct result of that addition or won't return at all. This means no wrap around overflow, no NaNs; this is vastly cleaner. However, as far as I know, this has nothing to do with CL in particular, this is presumably how Python or any language with a exceptions works. This is what I cannot fathom: that there are people that are willing to throw away this simplifying assumption because it means that your code might have controlled non-local transfer of execution. This is what Joel on Software directly says (linked elsewhere in this thread); exception handling is like goto, goto is bad, even when it is contained within an apparatus fixes its problems, like the exception handling apparatus. Or that people think the same amount of work is involved in either system? How does that make sense? Which way would you rather treat something like "add(a, add(b, add(c, d)))" because to my eye the C style handling adds a bunch of boiler plate code that I'd rather not write while adding little to no value. Like I was saying, I cannot fathom it so it is hard to form an argument against the alternative stance that I do not understand. Perhaps there are places where we want our execution so close to the structure of the code that handling errors C style makes sense, but I have to imagine that they are few and far between.

If we compare a more common example where people will place error handlers: writing to a file. Is it better to have writefile(file, data) return an int that indicates error, or is it better to just say "writefile puts this data in file, period". Here are two errors that might come up when writing to a file, we don't have write permission for that file or the disk is full. Where do you want to handle these errors? One error happens when we open it, the other happens when we attempt to write to it further down the call tree, but presumably we might want to catch both and deal with them at the same location. With exceptions you catch/handle the exceptions you are interested in. When returning error codes you have to manually defer the error up the call tree, affecting the interface of every calling function up to the highest function that can actually handle the error. So you can add the boiler plate code to combine and propagate errors up the call tree to your task list now. At the root of this is the exact same issue as the previous point, it adds syntactic and mental overhead for the programmer.

This article seems to have spawned some responses. Consider this post: [http://www.yosefk.com/blog/error-codes-vs-exceptions- critica...](http://www.yosefk.com/blog/error-codes-vs-exceptions-critical- code-vs-typical-code.html) He makes claims like in the code...

open_the_gate() wait_for_our_men_to_come_in() close_the_gate()

...if there is an exception inside wait_for_our_men_to_come_in then we'll never close the gate. While this is true for the code he's written, most people would (or should) consider that code buggy. In my experience and the comments of that post confirm it, most languages have a mechanism to ensure certain side effects happen even under non-local control transfer. Where are the points of intermediate state that he render exceptions equally bad as error codes? Are they the states that we explicitly account for in any bug free program, like closing the gate if there is an problem bringing the men in? I will reiterate, I truly am at a loss, this is not a rhetorical question. It seems like I am missing something.

To sum up: One method seems like a clean method of dealing with errors that will happen, the other seems like a nightmare syntactically and basically consists of code that I deeply feel should be up to a compiler to write.</comment></comment></comment></comment></comment>


Bug: unable to print from Open Office - <AUTHOR> https://bugs.launchpad.net/ubuntu/+source/cupsys/+bug/255161 <comment><USER2> [https://bugs.launchpad.net/ubuntu/+source/cupsys/+bug/255161...](https://bugs.launchpad.net/ubuntu/+source/cupsys/+bug/255161/comments/28)</comment>


Dealing with measles outbreak cost 20 times that of increasing vaccination cover - <AUTHOR> https://discover.dc.nihr.ac.uk/portal/article/4000312/dealing-with-a-measles-outbreak-cost-20-times-that-of-increasing-vaccination-cover?utm_content=buffer5b6f8&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer <comment><AUTHOR> The full title is "Dealing with a measles outbreak cost 20 times that of increasing vaccination cover"</comment>


Why airlines make flights longer on purpose - <AUTHOR> https://www.bbc.com/worklife/article/20190405-the-secret-about-delays-airlines-dont-want-you-to-know <comment><USER2> IMHO, many flights are late because airlines are extremely efficient, not because they are inefficient.

A plane is used as much as possible without any slack so any delay has a ripple effect throughout the day.</comment>


Someone Recorded Crickets then Slowed Down the Track, And It Sounds Like a Choir - <AUTHOR> http://truthseekerdaily.com/2013/11/someone-recorded-crickets-then-slowed-down-the-track-and-it-sounds-like-humans-singing/

<comment><AUTHOR> The Robbie Robertson album came out in 1994, this in 1992--Robertson credits the creator of the cricket record. A number of Amazon commenters mention it, for whatever that's worth: [http://www.amazon.com/Gods-Chorus-Crickets-Jim- Wilson/produc...](http://www.amazon.com/Gods-Chorus-Crickets-Jim- Wilson/product- reviews/1932192077/ref=dp_top_cm_cr_acr_txt?ie=UTF8&showViewpoints=1)

</comment><comment><USER2> Looks like a hoax, this is the original [http://www.youtube.com/watch?v=61ytg60AwOE](http://www.youtube.com/watch?v=61ytg60AwOE)</comment>


Hackers Steal $70M in Bitcoin - <AUTHOR> http://time.com/money/5053744/hackers-steal-bitcoin-nicehash/?utm_campaign=time&utm_source=twitter.com&utm_medium=social&xid=time_socialflow_twitter <comment><USER2> How is it that this can't be prevented by the Bitcoin network? The network should be able to mark coins stolen and unusable...oh wait it can't. Because in order to do that you'd need a trusted third party to verify the coins were stolen defeating the purpose of a distributed ledger that doesn't require third party trust. Yet another shortcoming of trying to replicate cash.

<comment><USER3> If someone stoles cash from you, how do you mark that cash as stolen?

<comment> murph-almighty FWIW banks will record serial numbers of bills that go missing after a robbery.

<comment><USER4> Is that actually true? I've heard it as well, but it seems like an impossible task for a bank.

Are they scanning all the bills that come in? Which bills are in which teller's drawer? I doubt it.

If they received new bills in sequential order from the mint and had them stolen, I could see how they would know the numbers. But then again, what's the point? Your average business isn't going to scan numbers, so by the time the bills pop up again, you have no idea the path they took.

I've heard that serial numbers from ransom money would be recorded. That makes a bit more sense as they are one-time events and there is value in knowing if you find money it came via the ransom.

<comment><USER5> Yes, bills are scanned and the system checks to see if they are marked as stolen.

<comment><USER6> Is that why small bills are preferred? Because they are less likely to be scanned? Or is another Hollywood fallacy that I've come to believe?

</comment></comment></comment></comment></comment></comment><comment><USER7> Tangent: why refer to these people as "hackers" and not "thieves"/"criminals"/" embezzlers"/...?

<comment><USER8> Because until very recently that is what hacker meant to regular people: "someone who bypasses computer security, usually to commit a crime"

<comment><USER9> "Until very recently"? So what does it mean now to regular people?

<comment><USER10> It is used as a synonym of "doer" or "builder" but in the software/internet related industries, e.g. this website. Which is a bit strange since "to hack" doesn't carry good connotations, neither a "hacker" in the original sense.

<comment><USER8> Similarly there is now this term "maker" which I find... ridiculous, to be honest. Are carpenters "makers?" What about electricians? Plumbers? Why does "maker" seem to imply a nerd with an Arduino or a 3d printer?

</comment></comment></comment></comment></comment><comment><USER11> Can someone walk me through how this happens from a technical perspective? Nicehash must keep their PK at some "super secret place" so they can sign transactions out to their miners. In an ideal situation that PK is unreachable even in a security breach—but if it's not well guarded enough then once that PK is found the floodgates are open. Is that correct? Also, from a technical perspective why would a pool keep so much BTC in a hot wallet? Shouldn't they be constantly distributing rewards out to miners, and just pocketing a % them selves which (you'd assume) they'd move to cold storage?

<comment><USER12> Fundamentally, it is difficult to protect 256 bits of information from a highly motivated attacker.

You can make it more difficult by using things like cold wallets with Shamir Secret Sharing schemes, but $70m of seemingly untraceable assets is an attractive target. Even if you require a quorum of ten people to access the cold wallet, that's still $10m per person if split amongst themselves.

And someone has to build that system in a trustworthy way in the first place.

</comment></comment><comment><USER13> Maybe they were hacked, maybe the owners stole it, you'll never know. And no one really knows the wallet of the mined coins so they can't really be traced outside of the company.

</comment><comment><USER14> Can someone explain how is it possible to steal Bitcoin if every transaction is recorded in a public ledger? Does not every bitcoin have its own signature which allows you to track its movement? New to this.

<comment><USER15> Yes it is possible to check the history of a Bitcoin and see that it has been stolen. Provided that you take the effort to do that.

This is no different than when a bank is robbed and banknotes are stolen. The bank might have written down the numbers of the banknotes and those can be published. But most shops won't check those when somebody buys something.

<comment><USER16> With bitcoins, it is easier to track the notes, but it is also easier to get rid of the association if you find someone willing to clean them for you.

Say I steal 10 bitcoins from you. I go to someone who cleans bitcoins for a cost of 10%. I send them 10 bitcoins, and they send 1 bitcoin to 9 different wallets (keeping the 10th as payment). That alone would allow you to still track it. But now add in thousands of other people sending them bitcoins on the same day, and some random pauses as to when they send the bitcoins to other wallets, and you are no longer able to tell which bitcoins in are associated with which bitcoins out.

Now, do you just get businesses to stop doing business with anyone (any wallet) that has ever received bit coins from the mixer? And there are many mixers out there.

And this is still simplified. You can be governments are monitoring and running statistical analysis on those mixers to try to find people laundering bitcoins associated with especially bad things. I'd even guess some of the bitcoin laundering operations are ran by governments in an attempt to better track the flow of bitcoins.

<comment><USER17> Not doing business with mixers: wow, what an interesting way to stir up trouble! Someone should create a service to distinguish "legit" from "tainted" Bitcoin. Let's see if Gresham's law applies so 1 bitcoin is no longer 1 bitcoin. What would the other exchanges do if one of them started trading these separately?

<comment><USER18> It's important to distinguish two issues: (1) whether the currency is usable as currency and (2) whether there are forensic clues enabling law enforcement to identify criminals. They're completely separate questions.

The value of a dollar bill is the same whether it was used in a crime. But if it has some ink on it, it might provide evidence that the person holding it robbed a bank. The ink doesn't keep the dollar from being usable.

It has to be this way. Otherwise money simply gets taken out of circulation, and people participating in the economy have to worry about whether money is money.

More: [https://www.reddit.com/r/Bitcoin/comments/1qomqt/what_a_land...](https://www.reddit.com/r/Bitcoin/comments/1qomqt/what_a_landmark_legal_case_from_mid1700s_scotland/)

</comment></comment></comment></comment></comment><comment><USER19> It's like MMORPG currency only more imaginary.

<comment><USER20> Whoa, edgy!

<comment><USER21> It is truly astonishing how salty the hacker news community is about BTX

<comment><USER22> I don't know, I'd probably be pretty salty too if I'd known of bitcoin for years, never bought any because I kept predicting its demise / uselessness, and was continuously made wrong by reality. This meme shouldn't make me laugh but seems fitting... [https://pbs.twimg.com/media/DQfNIzNVAAETVOB?format=jpg&name=...](https://pbs.twimg.com/media/DQfNIzNVAAETVOB?format=jpg&name=900x900)

</comment></comment></comment></comment><comment><USER23> Response from BitBank.nz [http://blog.bitbank.nz/nicehash-hacked-62m-bitcoins- gone-2/](http://blog.bitbank.nz/nicehash-hacked-62m-bitcoins-gone-2/) idk what its worth now probably 100m atleast lol

</comment><comment><USER24> What really pisses me off is how it got handled by NiceHash:

 _Alex Zvyozdny: Many of you already know that the site reddit spread information about the alleged hacking of our service. We hasten to assure everyone that your bitcoins are safe and sound. And we are the largest pool in the CIS countries are not going to close, but rather increase our presence in the regions. In connection with the increased number of those wishing to mine the crypto currency at our sites, as well as rent or lease capacities for mining, we conduct PLANNED technical works, which are to be completed on Friday morning. From December 8, the service will work in the standard mode. Since this is the most massive update in the last two years, we have indeed suspended all Bitcoin payments, and the funds were taken to a safe place. After the works - everything will be returned to their places. Please do not panic! Sincerely yours, NiceHash._

<comment><USER25> Can you source that quote? I only see instances of that in various comments on reddit/facebook posts, none from any official NiceHash account.

Gonna call fake news on that quote until proven otherwise. Lots of trolls/disinfo out there about this. e.g. [https://www.facebook.com/NiceHashSupport](https://www.facebook.com/NiceHashSupport)

That said, these guys probably exit scammed.

<comment><USER24> It's not fake, it was posted on FB, and then deleted when the truth finally came out.

</comment></comment></comment><comment><USER26> Take your best guess when Bitcoin will fall of the cliff: [https://twitter.com/BitcoinPlunge](https://twitter.com/BitcoinPlunge)

</comment><comment><USER27> Is there/can there be any proof that this wasn't an inside job by someone at Nicehash who just wanted $70M of Bitcoins?

</comment><comment><USER28> another day...</comment>


Ask HN: Startup records local HDTV, offers online DVR. I forget the name? - <AUTHOR>

And I completely forgot the name. Sorry to turn to HN for something like this, but for the LIFE of me, my Google-fu is failing.
The gist is that you pay them, and they DVR your local over-the-air programming, and let you access it online. The name was very soft-sounding, and not a word. Akin to "Hulu" in that regard.
I first found mention of it here, and now I'm blanking. Anyone recall it offhand? <comment><USER2> Bamboom?

<comment><AUTHOR> YES! THANK YOU!

Seriously, I'd racked my mind trying to get that name. I guess it wasn't quite as vowel-heavy as I thought... But that was it; thanks a lot mantalk!

</comment></comment><comment><USER3> zediva

<comment><USER4> They are the DVD rental people. I remember seeing the service the original poster is talking about, but the name escapes me as well.

<comment><AUTHOR> dsl's right, that wasn't it, but thanks for trying, ddorian43.</comment></comment></comment>


IOS Icons in Pure CSS - <AUTHOR> http://graphicpeel.com/cssiosicons

<comment><USER2> Beautiful. Well done. The rest of your work is also very sharp.</comment>


Show HN: LazyCode – C++14 composable, lazily evaluated map, filter, fold - <AUTHOR> https://github.com/SaadAttieh/lazyCode <comment><USER2> And some user just opened an issue titled "Where are the tests?" and nothing else. Sure that's a valid concern, but that's the kind of attitude that would make me disable or lock GitHub issues in a project altogether (I have no relationship at all with this specific project).

</comment><comment><USER3> Composable, lazily evaluated map, filter and fold in C90:

      This is the TXR Lisp interactive listener of TXR 204.
      Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
      1> (take 15 [keep-if* oddp (mapcar* [dup *] (range 0))])
      (1 9 25 49 81 121 169 225 289 361 441 529 625 729 841)

Lazy keep-if: [http://www.kylheku.com/cgit/txr/tree/lib.c?id=c310771b221125...](http://www.kylheku.com/cgit/txr/tree/lib.c?id=c310771b221125d3ff419662ce74f6b505fe638f#n1874)

Lazy mapcar: [http://www.kylheku.com/cgit/txr/tree/eval.c?id=c310771b22112...](http://www.kylheku.com/cgit/txr/tree/eval.c?id=c310771b221125d3ff419662ce74f6b505fe638f#n5170)

Lazy range: [http://www.kylheku.com/cgit/txr/tree/eval.c?id=c310771b22112...](http://www.kylheku.com/cgit/txr/tree/eval.c?id=c310771b221125d3ff419662ce74f6b505fe638f#n5397)

P.S. _dup_ generates a one-argument function which duplicates its argument into two places and calls another function. [dup *] gives us a squaring function, thus.

</comment><comment><USER4> Is the pipe idiomatic c++ or is this an operator overload that requires readers to go learn a new piece of syntax?

<comment><USER5> The pipe is an operator overload. That said, while I wouldn't exactly call it idiomatic, it's not entirely unheard of in third party libraries. RxCpp ([https://github.com/ReactiveX/RxCpp](https://github.com/ReactiveX/RxCpp)), the C++ ReactiveX library, makes use of a similarly overloaded pipe operator, for example.

Personally, I think I'd be more apt to use the "functional" style.

</comment></comment><comment><USER6> Just read through the code, really easy to read. Nice post, thank you.</comment>


Self-aligning heliostats arrive to slice CSP costs - <AUTHOR> https://analysis.newenergyupdate.com/csp-today/self-aligning-heliostats-arrive-slice-csp-costs <comment><AUTHOR> As a CSP researcher I find this motivating, because we are working on a system that does not require calibration at all.

Nevertheless, such self-aligning approaches are not explained at all which is quite annoying.

Our particular approach is based on machine learning for object detection using an embedded computer.

We have published several papers about this idea and also an article explaining our approach: [https://mechatronicsblog.com/smart-solar-tower- power-mockup-...](https://mechatronicsblog.com/smart-solar-tower-power-mockup- based-on-deep-learning-for-computer-vision/)

We did not get much attention but we hope that we can keep working on this and get funding to develop this approach for real systems.</comment>


New Zealand spying on Pacific islands, Snowden leaks say - <AUTHOR> http://www.bbc.com/news/world-asia-31741564 <comment><USER2> NZ Prime Minister John Key in August, 2013: "I'll resign if GCSB conducts mass surveillance". Well, now'd be a good time.

Source: [http://www.nzherald.co.nz/nz/news/article.cfm?c_id=1&objecti...](http://www.nzherald.co.nz/nz/news/article.cfm?c_id=1&objectid=11111384)

<comment><USER3> I get sooooo cross when I read anything that Key says.

 _" If I wholesale blatantly flout the law as Prime Minister I'm never going to survive anyway."_

That's such a twisted (and effective, it seems) way of convincing people that he hasn't been involved in any wrong-doing.

Let us not forget his statement on the GCSB bill that allowed sweeping powers for the spy agency (under his control) [1].

 _" All they can do is protect you, so it's against malware or a virus. ... On your computer at home you almost certainly have Norton Antivirus...that is exactly what that is, at a much higher level."_

Slippery doesn't even begin to describe the character of John Key.

[1] [http://www.3news.co.nz/tvshows/campbelllive/john-key- defends...](http://www.3news.co.nz/tvshows/campbelllive/john-key-defends-the- gcsb-bill-2013081419) (from 8:00 in the video)

<comment><USER4> Well..

>Last month, Auckland man Shane Warbrooke put in an OIA request to the prime minister's office, asking for "any evidence to disprove the theory that Mr John Key is in fact a David Icke style shapeshifting reptilian alien ushering humanity towards enslavement".

>"To the best of my knowledge, no. Having been asked that question directly, I've taken the unusual step of not only seeing a doctor but a vet, and both have confirmed I'm not a reptile," a smiling Mr Key said today.

>"So I'm certainly not a reptile. I've never been in a spaceship, never been in outer space, and my tongue's not overly long either."

[http://www.3news.co.nz/politics/john-key-im-not-a- reptile-20...](http://www.3news.co.nz/politics/john-key-im-not-a- reptile-2014021217)

</comment></comment></comment><comment><USER5> So everyone's spying on everyone. Wonder if these guys could all get a wiki up and running, would save so much trouble.

<comment><USER6> There is essentially a wiki for the major English-speaking countries to share intelligence: [http://en.wikipedia.org/wiki/UKUSA_Agreement](http://en.wikipedia.org/wiki/UKUSA_Agreement)

</comment></comment><comment><USER7> Somehow, national security is contingent on knowing EVERYTHING the public says and does. Total war has gone digital.

I never thought I'd see the day where a sarcastic slippery slope argument about the Patriot Act made in 2004 would manifest into our reality.

<comment><USER8> >where a sarcastic slippery slope argument about the Patriot Act made in 2004

I think many people were non-sarcastically making these slippery slope arguments, at least in part because they feared these exact sorts of scenarios.

<comment><USER9> That's why slippery slopes are not always fallacies.

<comment><USER10> It's still a fallacy, arguing the fact that fallacious argument can turn out to be true is a fallacy fallacy :)

<comment><USER9> Wait what? Fallacy fallacy is arguing that "it's a fallacy, therefore it's wrong", AFAIR.

(Or, as it usually works over the Internet, "it pattern-matches some random fallacy list I vaguely remember, so it's wrong!!111".)

<comment><USER10> No I mean you said that "because it turned out to be true, the original argument wasn't a fallacy", which is kind of "reversed fallacy fallacy" I guess, but I don't think it matters which "direction" it goes for the name of the phenomena. I might be wrong, obviously. I'll ask around...

The more I think about it the worse headache I get, so I'll leave it at that and hope for the best.

</comment></comment></comment></comment></comment></comment><comment><USER11> Yeah, that New Zealand imperialism has been getting out of hand lately.

</comment><comment><USER10> As a wannabe-kiwi, I'm hardly surprised. PM Key has been 'cooperative' with the US in most things so it's not surprising Five Eyes are being used to its/their fullest potential. Good thing GCSB has been talked about a lot even before this revelation... And about TPPA.

<comment><USER12> Hey there, wannabe Kiwi. Look me up if you want to hit the ground running with connections to the startup/tech world. I'm "Nat Torkington" and google finds my contact details. Always happy to help Kiwis and wannabe Kiwis :)

<comment><USER10> I appreciate the offer, but I'm currently stuck in EU railway sector and I think we both know what state is KiwiRail currently in, heh.

</comment></comment></comment><comment><USER13> I wonder, are all these leaks actually still from Snowden himself or is the name being used as a cover/branding for other sources now?

<comment><USER14> Snowden leaked a huge number of classified documents to journalists, and ever since, those journalists have been sorting through the material and publishing stories based on what they find.

In this case, the leak came by way of _The Intercept_ , which employs Glenn Greenwald as an editor, who got the documents from Snowden in person in Hong Kong before Snowden went into hiding. So I don't see any reason to assume they're lying about where the material is coming from.

</comment></comment><comment><USER15> So is it mostly about French territories ? I don't think that the Vanuatu or the Fiji are a huge threat on the global scale.

<comment><USER16> Fiji has had a series of military coups in recent times. Of course NZ (and others) monitor them.

<comment><USER17> By all means, if New Zealand is worried about Fiji military coups, then it's the duty of New Zealand's intelligence service to monitor the Fiji military.

The problem isn't that some nation is spying on some other nation, it's a problem of scale and scope. Fearing a military coup does not warrant "intercepting and storing content and metadata of all communications" happening on that island.

</comment></comment></comment><comment><USER18> "a foreign intelligence service that wasn't gathering some foreign intelligence, I'd ask him 'what the hell are we paying the money for?"

The ye old argument of a defensive force. Why should we spend all this money on a army that just sit at home and wait for others to attack?

This is of course different from when you have a defined target which threatens the country in a specific way. At that point, a defensive force and intelligence service should be deployed as it is appropriate to address that target.

<comment><USER19> Surely the point of the intelligence services is to find out who is threatening a country in a certain way?

<comment><USER18> intelligence services should operate the same way as the police do. The police job is to find out who commit crimes, but that doesn't mean they should invade peoples home at random in order to find out who the criminals are. Their start position is one where they suspect a specific crime is committed by specific people, and then go after those people using methods approved by society.

</comment></comment></comment><comment><USER20> Full take, my a... Put those chaps in prison. There is simply no other place on earth for them.

<comment><USER20> To all the downvoters, I censored the a __\- if you have other reasons to not agree, please elaborate in a reply. Thank you.

<comment><USER21> >please elabore in a reply

Your comment is useless and contributes nothing towards a discussion, so there's that.

<comment><USER20> That's your opinion. My comment was to express my outrage - if that can't be part of a discussion, then...?

<comment><USER22> Welcome to HN, where your comments aren't censored, but insead they are 'groomed' by those who consistently cherish 'valuable' conversations by pandering to 'karma' points.

The 'correct' dialog is to discuss how it's natural for our systems of governance to want to spy on everyone, and the 'correct' actions fall between accepting this or petitioning our masters to roll back 'some' of these advances.

Your individual outrage is of no value to the collective.

<comment><USER23> pastas, your account is hell-banned so you need not worry about being downvoted anymore. As for your -10, you have your own narrative but let me give you the perspective of someone who had little interest in the "disassociating woman" article and no personal stake in it. Your first two comments on HN ever are a single word discounting the post, with nothing to back it up. To many (including myself) that's a waste of electrons. Your more eloquent responses amount to the same thing, just with more words. You can write that off as "just <my> opinion" (to which I add "duh"), but ask yourself what it was you said that has more substance than just being contrarian.

In summary, if you come into a thread shitting all over things with nothing to back up what you say, you'll get downvoted.

<comment><USER22> I think you robo-posted to the wrong thread bud.

#edit then in that case you'd think the post would be judged as having no value and be downvoted.... oh wait, that would require a lack of hypocrisy.

<comment><USER23> Sorry, can't reply to dead posts so I highjacked your reply. If you don't have _showdead_ turned on, you won't see the dead post from user _pastas_ that I replied to. _pastas_ has a theory on his -10 karma, a theory with which I disagree. The unrelated article was referenced because his comments there make a better example.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER24> The righteous West is -has always been- corrupt and unworthy of trust.

<comment><USER25> I don't comment here to necessarily disagree with your assertion... only to say that the same is true for the rest of the world. ALL nations... are corrupt and unworthy of trust.

It probably doesn't even make sense to say that this or that group of nations is "worse" than the others at this point in mankind's history. That would be like walking into a room full of pregnant high school girls... and picking the one you feel is the "most virgin".</comment></comment>


RailCar: Rust implementation of oci-runtime - <AUTHOR> https://github.com/oracle/railcar <comment><USER2> This is great. I really wish the container boom started with a more Unix philosophy around containers; package "images" as a tarball, run the container with a wrapper like runc. The container inherits Stdout, Stderr, Stdin, etc. You can pipe the output to log aggregation, etc. Small, sharp, reusable tools.

Containers should just be the new static binary. Instead, we have Docker "Daemon"'s that can crash.

<comment><USER3> I'm one of the runc maintainers, and have been thinking a lot about how to create a new runtime from scratch. Despite a lot of flaws, runc's daemonless design is something that we did that was the right decision.

However, I've also been thinking about ways to defend against hostile containers. And it turns out that a lot of the tricks you need to do are very hard if you don't use a daemon and are impossible if you don't want to pollute the host namespaces.

I've spoken to Vish (the author) and we'll see if we can include some of my architecture reworks into railcar or if I'll go off and do my own thing.

Oh, and by the way, if you like runc's design you should probably go look at rkt. I'm planning on putting in the work to make rkt work without systemd, but the really nice thing about rkt is that it's architecture is also completely daemonless.

<comment><USER4> I'd be curious if you could share some thoughts on lxd/lxc - Canonical's foray into containers?

<comment><USER3> I'm actually good friends with a couple of the maintainers of lxc/lxd :P. It's not really fair to call it "Canonical's" \-- it existed before the lead developers started working for Canonical and it still gets plenty of contributions from outside of Canonical.

lxc and lxd have quite a large amount of very interesting technology and features. lxd has live migration and a whole host of other cool features, and lxc is quite well designed from my experience. Also the developers are quite clever folks IMO. I've been bouncing some of my ideas for a new container runtime off them, since they also have seen the issues I've seen with the current state of things.

The big difference is that lxc/lxd is designed to "boot" an operating system as a container, not just to run a single application. While there is actually no significant technical difference between the two usecases, the features that have grown out of each runtime are tailored for those usecases. lxc lets you log into a console (in the same way you would on a physical box) and do a full getty login. runc has tools for managing containers in a far more "micro- service" sense.

I really wish that the lxc folks had helped us with the OCI, but I have a feeling their usecases are so different to us that it's unlikely we could reach agreement in the spec. Overall though, lxc definitely has a place and it's a shame more people don't try it out.

</comment></comment></comment></comment><comment><USER5> There was a blog post from Oracle describing this project last week: [https://blogs.oracle.com/developers/building-a-container- run...](https://blogs.oracle.com/developers/building-a-container-runtime-in- rust) , and a corresponding reddit thread with the author's participation: [https://www.reddit.com/r/rust/comments/6kaexs/building_a_con...](https://www.reddit.com/r/rust/comments/6kaexs/building_a_container_runtime_in_rust/)

<comment><USER6> I think this was the reddit thread, [https://www.reddit.com/r/rust/comments/6kaexs/building_a_con...](https://www.reddit.com/r/rust/comments/6kaexs/building_a_container_runtime_in_rust/)

<comment><USER5> Ah, thanks. :)

</comment></comment></comment><comment><USER7> For context, some people at Oracle want to use containers but they don't want to use layers, overlayfs, or "docker pull": [https://blogs.oracle.com/developers/the-microcontainer- manif...](https://blogs.oracle.com/developers/the-microcontainer-manifesto)

I guess this project is perfect for them but it's probably a bit impoverished for other people.

<comment><USER8> I would think Oracle could afford a copy editor for their world-facing communications. That post could use a once-over by a competent editor.

That said, the complaints they have about Docker are extremely valid. I've been grumbling about them for years. Though some of their solutions seem clunky. The /read, /write and /run directories seem...weird, at best.

</comment></comment><comment><USER9> OCI = Open Container Initiative

(I think. I wish the README would have made that more clear.)

<comment><USER10> Thanks. I'd assumed it was Oracle Call Interface (OCI), the C API for Oracle DB...

</comment></comment><comment><USER11> It's always good to see more development in this area. Here's hope the runtimes become as rock solid as they should have been in the first place (given their central role in the container story).

I can't help but notice the UPL license is an odd choice. The whole thing about contributors granting patent licenses.. isn't that a legal minefield?

<comment><USER3> Both Apache-2.0 and [L]GPLv3 have patent licensing clauses as well. Patents are a more general problem that you cannot solve with just a license, but patent license clauses avoid patent treachery[1] by construction -- as long as you can trace back your copy of the software to a patent holder then the patent cannot be used against you. This is obviously not ideal, the ideal solution would be to eradicate the concept of software patents entirely, but as far as legal hacks go this is as good as you can get.

Patents are a legal minefield (for users) whether or not your licenses talk about them (though licenses that remain silent about patents open you up to patent treachery) because of the laws that surround them (independent discovery is not protected). As for patent holders, they simply are not allowed to both distribute software under those licenses and harass users of said software using patents contained in the software. I think that's more than a fair trade (in fact, the scales are tipped in their favour because they can still sue you if someone else independently discovers something they patented).

[1]: [https://www.gnu.org/licenses/license- recommendations.html#sm...](https://www.gnu.org/licenses/license- recommendations.html#small) \-- In particular `[...] it does prevent patent holders from setting up a "bait and switch" where they release the software under free terms then require recipients to agree to nonfree terms in a patent license.`

<comment><USER11> Thank you, that was very informative.

</comment></comment></comment><comment><USER12> Author here. I missed that this hit hacker news. Happy to answer any questions if people are still lurking.

</comment><comment><USER13> An a-class company (size/influence wise not niceness) like Oracle adopting Rust is quite big news!

<comment><USER14> It is. The same author is writing quite a bit of Go in Oracle Github organization. I think Java/JVM is going to be less relevant in containerized applications and systems.</comment></comment>


Ask HN: iOS app idea – need developers - <AUTHOR> I'd like to work with a developer (or a team of developers) in order to build an iOS app. I have the idea and the wireframes, though I need someone to write the app for me. Do you have any recommendations? Are there services out there where I could share my wireframes, remotely supervise and of course pay for the development of the app? Besides google I think the hacker community is a very trusted resource.<p>Thanks a lot for any info! <comment><USER2> Hello, shoot me an email, my email is in my profile. I have an App Building Platform, and you can manage the app building process yourself with the help of hundreds of other programers. The basic idea is to break down the app into very small pieces, and once those pieces are built and tested, they will be assembled just as quickly and inexpensively.

I have the tooling, infra and the network of programmers, and anyone who might be interested in working with me please email me as well.

<comment><USER3> both op and you are the same person?

<comment><USER2> No</comment></comment></comment>


Apple, in refusing backdoor access to data, may face fines - <AUTHOR> http://zdnet.com/article/apple-in-refusing-backdoor-access-to-data-faces-huge-fines <comment><USER2> US Constitution Amendment IV

 _The right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures, shall not be violated, and no warrants shall issue, but upon probable cause, supported by oath or affirmation, and particularly describing the place to be searched, and the persons or things to be seized._

Probable cause must _precede_ the search & seizure of "papers" (presumably electronic messages are included by extension).

US Constitution Amendment III

 _No soldier shall, in time of peace be quartered in any house, without the consent of the owner, nor in time of war, but in a manner to be prescribed by law._

A reasonable interpretation includes ubiquitous monitoring of an individual without actionable cause. (As in: the "quartering" referenced has historically been used in part to monitor the home's occupants.)

US Constitution Amendment V

 _No person shall ... be compelled in any criminal case to be a witness against himself ..._

Preemptively gathering (including tapping information storage for access on demand) broad-ranging evidence, before a criminal case is justified, is not justified. The enumerated right is moot if the government has preemptively aggregated everything that otherwise could be protected by this right.

<comment><USER3> > and no warrants shall issue, but upon probable cause

In the case written about here, the Justice Department has a search warrant issued upon probable cause.</comment></comment>