HN user

bobbyrullo

39 karma
Posts0
Comments8
View on HN
No posts found.
Atari 800XL Remake 3 years ago

Archon might be my favorite game of all time...But what's this with the overpowered unicorn? Was it way more powerful than the dark side equivalent (basilisk?)? Did they release another 8-bit version or something?

Emacs 29 is nigh 4 years ago

I'm at an organization where our dev machines are in the cloud. Most folks are indeed using VSCode remotely, but I'm happy with emacs.

The combo that works for me (on MacOs locally) is daemon mode and X11 forwarding...but using x2Go instead of vanilla "ssh -X". I end up with XQuartz windows that behave (mostly*) like other MacOS windows and pretty good performance.

If I'm at cafe or somewhere with spotty internet, I'll forgo the X stuff and just use mosh and text only emacs, but I pretty much never do that anymore.

(* mostly, meaning that for some reason tools like divvy and other things that manipulate/resize windows just don't work with X Quartz windows)

I had the same questions, and it's very hard to find the answer - took me a very long time to piece this together but this is how Google does it:

1) You create a "normal" client in Google Developer console (i.e. a web client) 2) You create a native/Android client in the same project. This client is shared across all phones. 3) You add a scope of audience:server:client_id:$NORMAL_CLIENT_ID to auth requests from the mobile. 4) You get back token minted for the web client, from the native client!

This is how it works:

https://developers.google.com/identity/protocols/CrossClient...

The reason it is safe is because you can only do the cross client stuff from a mobile client, which disallows any redirect urls except for localhost and a couple of other special URIS (see https://developers.google.com/identity/protocols/OAuth2Insta...)

It's ok that the secret is not really secret because it's not possible to use it to making a Phishing site since the redirect URL is localhost.

I guess that doesn't answer your "how does it identity the app developer" but it does tell you how these things are deployed at least, and the important fact that there's just one client (not one for every device)

Sure, there's lots of trade-offs - you can't build anything significant without trade-offs. Also, you can still say performance is a value and trade it away for other things, eg GC. It's a bit silly to say that if something isn't as fast as C++/C right away then it doesn't take performance seriously. I don't think anyone's being dishonest in making such trade-offs - if you have multiple competing values then you need them.

The big difference with stuff like GC and re-writing stuff in go slowing the compiler time is that they are not inherent to the language. That stuff can and will improve. With generics if done incorrectly, it's more or less permanent. So I appreciate the conservatism there, and don't think it's fair (or accurate) to say that it's dishonest.

That's a different criticism. That's the "Go Needs Generics" issue.

I don't disagree with it, but I also agree that there hasn't been any good solutions proposed for generics that meet the requirements that are at the core of Go: namely, performance of the compiled program, performance of the compiler, and performance of the developer.

For every "quirk" mentioned in this article there are very good reasons for it, which the author lacks the imagination or patience to try and reason through. Point 4 is perhaps the best example.

So given an interface Foo and a struct FooImpl which implements Foo, why can't we pass a slice of []FooImpls to []Foo? It's because the creators of Go are lazy and arrogant and incompetent and don't care right?

No. Consider the situation where a []FooImpl is passed to a function F(f []Foo). This function decides to change one of the elements of the slice to a different implementation, say FooImpl2, eg. f[0] = FooImpl2{}. Now the original slice of []FooImpl's has a FooImpl2 in it. Oops, we broke type safety. Now consider what it would take to make this work - you'd have to somehow guarantee that functions which take []Foo don't mutate the slice. Is that possible? Is it possible to do quickly, and still have a language that compiles very quickly? Or we could introduce "const" and all those things from C++ but that's a whole new level of complexity to the language. And what about the performance penalties? A struct is a different size than an interface, so what code is emitted during compilation, something that can handle iterating over []your_interface and []your_struct?

So next time you think "Gosh, this bit of Go really sucks" take a moment and think about why it was designed that way. Because the fact is, it was almost definitely designed that way, as opposed to just overlooked or neglected. You may not agree with the choice that was made, but with the people who work on Go, I can guarantee that there was a conscious choice that was agonized over and discussed endlessly, just not with you in the room.