Hacker Newsnew | comments | ask | jobs | submit | CoffeeDregs's commentslogin

Agreed. The modals in Angular-UI (which I use) don't seem very AngularJS-ish: the Modal controller creates the ModalInstance controller? I googled for a bit to make sure that I really had to create two controllers in order to manage one dialog. Also, $scope management in AngularUI-Bootstrap dialogs seems a bit wonky.

reply

badman_ting 10 days ago | link

I found that confusing as well.

reply


Agreed. Especially when they can get a giant Google-sized, caching reverse proxy (CDN) simply by setting cache headers appropriately.

http://stackoverflow.com/questions/5617322/how-to-enable-cac...

-----

boundlessdreamz 24 days ago | link

How does that help when your content is in Cloud Storage? Is there an app which serves content out of Cloud Storage and runs on app engine? (I haven't worked with app engine)

You can set caching headers on Cloud Storage also. But that doesn't help when 1. you have a large number of requests with cold cache 2. want the flexibility to keep cache time small. Unlike cloudfront there is no purge method in GCS. GCS doesn't guarantee to serve new versions until the old one's cache time has expired.

-----


Certainly you can. In fact, the OP did exactly that and his article is at the top of HN.

My hope is that we can just carry on with our dev work and Windows will slowly fade away as a platform for developing anything but SharePoint intranets...

[Note: I don't have a neckbeard, but I do run Debian testing.]

-----

recursive 25 days ago | link

But... but... some of us our doing our development on Windows and loathe Sharepoint.

-----


Interesting. Python support is provided by Heroku build packs?

    To deploy Python applications to BlueMix, use
    $ cf push -b https://github.com/joshuamckenty/heroku-buildpack-python
Also, I don't see any pricing, so that's a little nervous-making.

Nice that you get an 8GB memory allocation to play with, though, shared amongst your various apps.

-----


The lack of benchmarks comparing Mono to the CLR (C# VM) is very frustrating. Apparently, the lack of benchmarks is due to Microsoft's license forbidding the publication of benchmarks without Microsoft's permission (common practice among commercial vendors?).

Fortunately, we have the Benchmarks Game and that shows Mono performing well [on synthetic benchmarks...] when compared to a variety of languages.

vs Java: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...

vs Go: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...

vs Python: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...

-----

bhauer 51 days ago | link

We have included Mono in our Framework Benchmarks project for some rounds now. However, we have recently set up a new hardware environment and we're not having any luck getting Mono installed on that environment [1]. It's simply not installing correctly for us. We're not Mono experts, so we're probably doing something wrong.

If anyone is interested in lending a hand, we'd appreciate it since we'd like for the Mono tests remain in Round 9. Thanks!

[1] https://github.com/TechEmpower/FrameworkBenchmarks/issues/78...

-----

nswanberg 51 days ago | link

Thanks. It took a little while to find, but if anyone is interested in comparing Mono to the CLR for themselves (and likely do some work to adapt the system to Windows), here's where to start: http://benchmarksgame.alioth.debian.org/play.php#languagex

-----

igouy 49 days ago | link

The measurements scripts provided on the benchmarks game website are written in Python 2.5+ and worked fine on MS Vista using:

- Python 2.5+

- Python Win32 Extensions (for win32 process monitoring)

- GNU Make for Windows

- GNU DiffUtils for Windows

Download bencher.zip from:

https://alioth.debian.org/frs/?group_id=100815&release_id=18...

-----

antihero 51 days ago | link

Can someone not just make some code that does the benchmarks, and publish that?

Then some other helpful person can pastebin the actual results.

-----

igouy 51 days ago | link

>>Microsoft's license forbidding<<

I seem to remember that changed; and for a couple of years the benchmarks game did provide measurements for C# F# (.Net and Mono) and Java on MS Vista.

-----

mands 51 days ago | link

I think if you run a recent Mono, with the sgen GC using the LLVM backend and turn off array bounds-checking performance is supposed to be pretty impressive. (I recall Miguel saying within 10-20% of C++).

Having said that, I've had no performance issues running 3.2 on Linux in general.

-----


I hesitate to say this, but I'm a big fan of cubicles... But not the cubicles you're probably thinking of...

I'm a fan of 4-8 person teams attacking problems together and I've found flexible cubicle arrangements to be very effective. At one company, we could change around our cubes (albeit not terribly frequently) and it was great to be able to create a multi-person office with a conference table for your team (e.g. PM, designer, developers). We had tight collaboration and our own private space without being distracted by the larger company. Of course, this style of organization also affect project management, etc, but it was quite effective.

-----

mtrimpe 53 days ago | link

I'm reading PeopleWare right now which deals with this issue at length and their conclusion is quite similar to yours.

In retrospect it's as simple as it's obvious: people should be allowed to setup their offices in a way that works for them.

Interestingly enough this all comes from the original patterns book, the one which concerned itself with actual architecture.

It essentially states that people should create their own space and that structure and order should only be imposed through adherence to shared general principles.

Many of these principles seem so simple and obvious yet are so often forgotten in practice, such as that the wall should be far away enough to give your eyes a chance to relax.

Another one was that the sounds you heard had to be similar to that of your own, which seems strikingly true in my own experience.

-----


I've seen that, too. One of my clients redid their marketing site 3x in one year, each time claiming incredible improvements. The incredible improvements turned out to be local hill climbing, while the entire site's performance languished... 3-4 years ago there were a ton of blog posts about how a green button produced incredible sales when compared to a red button. And so everyone switched to green buttons...

By contrast, I've evolved multiple websites through incremental, globally measured, optimizations. It's a lot of fun and it requires you to really understand your user (I've called AB testing+analytics "a conversation between you and your users"). But, as you point out, it can be tough to get statistically relevant data on changes to a small site. That's why I usually focused on big effects (e.g. 25%), rather than on the blog posts about "OMG! +2.76% change in sales!". That's also why I did a lot of "historical testing", under the assumption that week-week changes in normalized stats would be swamped by my tests.

-----

patio11 53 days ago | link

under the assumption that week-week changes in normalized stats would be swamped by my tests

This is an enormously problematic assumption, which you can verify by either looking at the week-to-week stats for a period prior to you joining the company, or (for a far more fun demonstration) doing historical testing of the brand of toothpaste you use for the next 6 weeks. Swap from Colgate to $NAME_ANOTHER_BRAND, note the improvement, conclude that website visitors pay an awful lot of attention to the webmaster's toothpaste choices.

-----

ernopp 53 days ago | link

Full disclosure: I work for Qubit who published this white paper.

This kind of "historical testing" (I think people often call it sequential testing?) can be pretty dangerous even for large effects. For example Christmas might be a really good time to change the colour of all the buttons on your site and see a 50% increase in sales.

-----

lifeformed 53 days ago | link

Yes. This kind of micro-A/B testing ("red or green buttons?") feels analogous to premature optimization when coding. Don't worry about the tiny 0.0001% improvements you get from using a for-loop over a while-loop; improve the algorithm itself for order-of-magnitude changes. Focus on the big picture.

-----

lifeisstillgood 53 days ago | link

Can you expand? does globally measured optimisations mean the whole site saw a 1% rise after we did x? why is that different to a/B testing?

-----

CoffeeDregs 64 days ago | link | parent | on: Moon

Before this post, I was thinking about watching Moon again. It's such an incredible and unknown film. I will watch it again.

If you haven't seen Moon, then the following song will not make sense, but the sense of desolation and uncertainty rhymes with the film. The ending of the song captures the denouement @ 7:20.

http://grooveshark.com/#!/s/Downfall/2VQtYZ

Moon was fantastic.

-----

_mulder_ 63 days ago | link

Clint Mansell's original soundtrack is absolutely fantastic. I read they managed to get him involved in the film because it was during the writers strike 07-08 (remember that?!) and Hollywood had ground to a halt, hence Mansell and ilk were looking for projects to keep them active.

I like your song, but it's a different vibe. To my ear, it sounds a bit too military to be Moon. I do like the vintage synth sounds though!

-----

lcrs 62 days ago | link

I remember hearing at the time that the reason they were able to build such a big set for the moon base was because the stages were mostly empty, also due to the writers' strike.

-----

CoffeeDregs 66 days ago | link | parent | on: Toward Go 1.3

First, I apologize for bringing up something that has been brought up since the birth of Go...

I'm surprised at the lack of progress in generics for Go. But more than progress, I'm surprised at the lack of a story about generics in Go. Yes, the FAQ waves its hands at complexity, but the lack of discussion and/or proposals puzzle me. The wiki page about it (https://code.google.com/p/go-wiki/wiki/GoVsGenerics) is tiny and feeds from this discussion (http://groups.google.com/group/golang-nuts/browse_thread/thr...). I would be much more interested in Go were there some evidence for the intent to implement generics. A related concern is that adding generics will have a significant affect on libraries and existing code, so adding generics will become harder the longer Go waits.

I would be very happy to have the Go team say: we're going to focus on adding generics to Go in 2.0 and will be considering how to get there sooner than later; that said, we don't know when 2.0 will be released, but building in generics will drive 2.0.

Note: I understand the workarounds, but they're either hacky or have terrible performance. And I also understand that users of Go say that they don't miss generics, but I'm just not comfortable believing that.

-----

tptacek 66 days ago | link

There is a story about generics in Go. The story is, a variety of complex programs are being built and deployed in Golang without generics, which makes it an open question as to whether they're required at all.

Golang doesn't have to be all things to all people, nor does it have to fulfill every programming task any one developer has.

I would be just as happy at this point to see the Golang team put generics to rest. And I like generics, and have been annoyed by their absence in Golang before!

-----

vinkelhake 66 days ago | link

The story is that the Go designers saw the value in generics and added a bunch of generic container types to the language. They are also saying that if your needs aren't covered by these built-ins, then you have to build something on your own and you cannot construct something that provides the safety and ease of the built-ins.

> a variety of complex programs are being built and deployed in Golang without generics, which makes it an open question as to whether they're required at all.

And a variety of complex programs have been built and deployed in assembler. There are arguments against adding generics, but the fact that people get by without them isn't a convincing one.

-----

enneff 66 days ago | link

The story is that generics for Go is an ongoing research project for the team. We are not going to put them into the language until we are sure that we have a satisfactory way of doing it and that the end result is a net win.

-----

coldtea 66 days ago | link

>The story is that generics for Go is an ongoing research project for the team.

I don't see that in real life. That's just a "shut up" story employed like 4 years ago. If it's an "ongoing research" project, where's any researchy output?

"Python 3000" was once a research project and had tons of proposals and research done on various features. Closures in Java were researched, and there were implementations tested. ES6 was an ongoing effort to add features to Javascript, and there have been test implementations, shims, etc before it's out.

All languages that wanted to add a feature had attempts by various key developers to add these to them, proposals, papers, testing, requests for comments, etc. Where are those regarding Go and generics?

-----

enneff 66 days ago | link

The various proposals have been circulated amongst a small group of core Go contributors. That has been sufficient to drive the process so far, with many options being explored in detail. The work continues to evolve.

We're not university professors. We're not publishing papers or other "researchy output". We're just trying to get stuff done. If we publish all the works-in-progress we will distract the community from the more pressing concerns of today's Go programmers. We all already spend way too much time reading mail, and generics is a hot topic (obviously). The last thing we need is more (redundant) mail.

-----

coldtea 65 days ago | link

>We're not university professors. We're not publishing papers or other "researchy output".

Well neither is Larry Wall, or Guido (well, is not working directly as such), or the Rust guys. But they still manage to put out proposals and describe their approaches to adding features, their progress and such.

I didn't mean "researchy output" in the academic sense. Just the results of looking into it, basically. Could be just a blog post. Or some email.

-----

pstuart 65 days ago | link

How's that Perl 6 coming along? I hear Python 3 is starting to gain traction too.

-----

babawere 66 days ago | link

Its as been a research project for a very very very long time now ...

-----

enneff 66 days ago | link

Yeah, we've been busy making the language, libraries, and tools great. Sorry about that.

-----

jlmendezbonini 66 days ago | link

Please ignore him/her. There are a lot of us who are very excited about the work the Go team is doing.

-----

coldtea 66 days ago | link

So instead of "research project", a better description would be "very low on the list of priorities, nobody cares about it"?

-----

enneff 66 days ago | link

No. People continue to work on it. A lot of time has been spent on it. I really don't appreciate your mischaracterization.

-----

coldtea 65 days ago | link

Well, I'm sorry, but I haven't seen this from following Go from a (small) distance -- and doing some work projects with it.

Perhaps those people working on it can give an update or some info on their work? Even a "we tried this approach, it's too cumbersome so we abandoned it" or "we pursue this idea, but we're still ways off" etc, would suffice.

-----

overcyn 65 days ago | link

Aren't you just kinda being a dick here? A go developer has directly responded to you multiple times, saying that this is a topic that they're actively researching. And you just keep replying with skepticism asking for actual proof.

No one owes you anything here. I hope you don't behave this way with other open source projects.

-----

coldtea 65 days ago | link

>And you just keep replying with skepticism asking for actual proof.

Should I just accept the same kind of answer we've had for 4 years on the Go webpage, and move on?

You talk about wanting "actual proof" as if it's a bad thing. Where's the harm in wanting "actual proof"? Did Ken Ham proved it overrated?

Notice how the top voted comment in this thread, showing a clear community interest, makes the same point:

"I'm surprised at the lack of progress in generics for Go. But more than progress, I'm surprised at the lack of a story about generics in Go. Yes, the FAQ waves its hands at complexity, but the lack of discussion and/or proposals puzzle me."

>No one owes you anything here.

That doesn't preclude discussion, having questions and, yes, even doubting overly generic answers. Noone owes anything to the Python community either, but they are far more open with such things.

Perhaps I want to know if Go wants to be a real community project, or a "developed by a core team at Google in secrecy you get what we want you to get when we want you to get it" thing.

-----

overcyn 65 days ago | link

> Should I just accept the same kind of answer we've had for 4 years on the Go webpage, and move on?

Yes. Clearly its time to find another language that better suits your needs and is managed more to your liking.

-----

coldtea 64 days ago | link

>Yes. Clearly its time to find another language that better suits your needs and is managed more to your liking

Isn't that like a really inadequate answer to people trying to critisize/improve things? I sure get the rednecky "If you don't like this country mister, then go live somewhere else" vibe from it.

Clearly the fact that you are satisfied with Go doesn't stop you from inteferring with people having discussions about its (perceived) shortcomings.

So why should my disatisfaction with it prevent me from discussing it Especially if its a dissatisfaction with some aspects of it, and not the whole thing? By the same logic, nobody should use anything (nor complain about anything), since all languages have shortcomings that they don't like.

-----

overcyn 64 days ago | link

You've misread my comments and are trying to make them into something they're not. I wasn't calling you out for criticizing Go or trying to discuss its shortcomings. I was calling you out for being a dick to Enneff. I think my original comment was fairly clear about this.

Anyways this is a pointless argument. I'm sure youre a great guy in person.

-----

coldtea 64 days ago | link

>You've misread my comments and are trying to make them into something they're not. I wasn't calling you out for criticizing Go or trying to discuss its shortcomings. I was calling you out for being a dick to Enneff.

Well, we appreared as representing the Go team, and then rehashed the old "we're actively looking into it" response. I was not trying to be a dick, just wanted something more concrete than that.

Plus, I felt like he contradicted himself, when replying to another comment and said something to the effect that they didn't do anything about generics because they are busy building other things. So I had to ask, which was it, were they actively looking into it or didn't have time and had it as a low priority?

-----

frowaway001 65 days ago | link

No, but he has all the right to question their claims of "doing all the research in secret" and call them bullshit if he wants.

Anyway, just consider what their behavior says about how they think of their users.

-----

overcyn 65 days ago | link

He has all the right to say whatever he wants and believe whatever he wants. Doesn't mean he should be rude.

-----

Dylan16807 65 days ago | link

Asking for a status blog post once every couple years is not rude.

-----

otterley 66 days ago | link

It took Java over 8 years to get generics. Be patient. :)

-----

coldtea 66 days ago | link

Yes, because it sure worked well for Java, this slowness...

-----

CoffeeDregs 66 days ago | link

In general, I agree. Go doesn't have to be all things to all people, but it could be more than it is with a story about how it would add generics. I think a lot of people are disappointed that Go doesn't seem interested in going beyond the "systems language" level; we were excited to use Go in a range of applications but were disappointed by our inability to write generic map/reduce/fold/etc functions.

>I would be just as happy at this point to see the Golang team put generics to rest.

Clarity on this point would be great. And update the FAQ.

As it is, Rust is looking better and better as Mozilla tightens it up.

EDIT: I added the Rust note after tptacek added his reply. Apologies to him.

-----

tptacek 66 days ago | link

So use Rust. Rust looks neat.

-----

jksmith 66 days ago | link

Let's remember that to the stakeholders, this stuff is just a means to an end. I'd like to see Go have generics as well, but after spending the last two weeks writing a service bus in Go, the work was by factors more productive than the same work I've done in C#, which seems to be trying to have every possible language feature ever created in it.

Sure generics would be nice, but getting my shit done and moving on to the next challenge is even nicer. Hopefully some carefully thought out additions to Go will allow me to have all this goodness at some point.

Sorry for drift, but I have to put in a word for formalized pre/post conditions in Go. Really enjoyed that stuff in Eiffel, and I think it would play in well with the judicious lack of exceptions (which I like).

-----

Locke1689 66 days ago | link

Hmm, I haven't implemented anything complex in Go, but I have read a fair amount of code and looked at the "spec."

What language feature(s) would you say greatly assisted you in Go?

There's a credible argument that C# is a very complicated language (it is relatively old and has undergone a significant amount of iterations, thus is quite large), but I don't usually find that programmers are defining their own subset of the language to program in (a la C++), which usually means that the complexity isn't that large for me.

If you have any specific complaints I would love to know them as C# is being actively developed right this second, including new language features (well, not by me, I'm on vacation :)).

If you feel that HN is the best forum, please feel free to forward them to the email in my profile.

-----

jksmith 65 days ago | link

For me it's the comparative noise level. C# is noisy enough. When combined with stick your code here framework and code generation, monkeying with IIS, and the rest of the msft box I'm thrown into regardless of app load and requirements, I just start detaching or worse am just worn out at the end of the day. Go asks for so little in the productivity I get in return. Haven't enjoyed writing code this much since my Modula-2 days.

-----

michaelwww 66 days ago | link

> by factors more productive than the same work I've done in C#

are you exaggerating here? C# is already the most productive language in my toolkit. It's easy to write reams of code that just works in C#. I should have a look at Go then. (edit forgot a word)

-----

finnh 66 days ago | link

I measure my productivity in a language by how little code I can write to accomplish my goal. You seem to be saying the opposite?

EDIT: I guess you are saying something slightly different: that you can produce reams of C# code that works out of the box without many iterations. "reams" to me implies boilerplate & excessive ceremony, but I shouldn't assume that about your work =)

-----

usea 66 days ago | link

Shouldn't productivity be measured in how much time it takes to solve problems? The amount of code produced at the end is only relevant if typing is a significant portion of your time spent. Typing is rarely my bottleneck.

-----

markkanof 66 days ago | link

Agree that typing speed is not the bottleneck when writing code, but there is something to be said for writing fewer lines of code that are also easy to understand (ie. overly clever code that is concise is often a negative). That should make maintenance and debugging easier as there is less code in which to introduce bugs and less code to load into your brain when returning to it later.

-----

michaelwww 66 days ago | link

No I wouldn't be saying I produce reams of boilerplate like it's a good thing ;) I meant, and I'm sure you've experience this, that the language doesn't get in the way of realizing the program that's still in my head. Every interruption spent tracking down some language quirk is probably double the time or more to get back into the flow of it. It's really a shame Microsoft doesn't do more to make C# more portable.

-----

codygman 66 days ago | link

The reason you write less code in Go is because there is less complexity. Similar to F# vs C#:

http://fpbridge.co.uk/why-fsharp.html (checkout the call graph comparisons. I believe a Haskell call graph would be similar, but I could be very wrong.

-----

bad_user 66 days ago | link

Kind of ironic that for making a point on C#, you're using F#, an FP language.

-----

codygman 66 days ago | link

I don't see the irony. It's a contrast of a class based and object oriented language vs a functional language. The functional language leads to a much simpler call graph than the OOP language.

-----

bad_user 66 days ago | link

The irony is that Go is not a functional programming language.

-----

codygman 66 days ago | link

You're right. One of the reason it has simpler call graphs and less complexity is because it is composition based and struct rather than class based.

-----

voidlogic 66 days ago | link

I agree from the original poster having done a lot of C/C++/Java/C# in the past.

-----

coldtea 66 days ago | link

Yes, he is exaggerating. Go is nowhere near as expressive or productive as C#.

-----

Buttons840 66 days ago | link

Is go really trying to stick to a "system level" language? The performance benchmarks I've seen seem to suggest it's no more suitable for that than Java, Haskell, and a variety of other "2 to 3 times slower than c" languages. Except I think Go might be the only one pushing itself as a system level language.

-----

dpritchett 66 days ago | link

I think it's occupying a nice spot on the spectrum between say C and Ruby. If you're implementing some CRUD app with a few hotspots, maybe you'll implement the whole thing in Rails, then break it out into an SOA with golang services powering the hotspots. Finally if you really need to you can hand-tune the hottest spots with some C code inside of your Go services.

One thing I've been enjoying out of the Go community is narrowly scoped command line tools. Heroku's CLI client runs on Ruby, but there's an `hk` variant written in Go that offers 90% of the functionality with a fraction of the runtime. More of that, please!

-----

NateDad 65 days ago | link

Calling it a system level language is a disservice. It's great for servers and commandline utilities. Canonical is working on integrating go with QML to be able to write nice GUI code that runs on all major platforms.

Go is actually quite well suited to GUI code, because it handles concurrent work very easily (i.e. work on the gui thread vs. work on a non-gui thread).

About the only thing you can't do nicely in go is write a domain specific language, the way you can in other languages that allow operator overloading.

Anything you might think about writing in Java or C# you can write easily in Go (once the GoQML stuff is ready that'll include GUI code). Most things you might want to write in python or ruby you can write easily in go (as long as you don't need monkey patching).

And note, I mean "Would be pleasant to write in Go" not "Would be possible but painful to write in Go"

If you're doing a lot of vector and matrices math, Go might not be the best language, since you can't operator overload and thus can't make the code look like the math it's trying to replicate. It would still work and would still be fast and accurate and nicely concurrent... but most people doing that kind of math programming have come to expect that parts of their code will look like math, and in Go it won't.

-----

joncooper 66 days ago | link

Totally agree. Go is a superb systems language. But I wouldn't use it for a CRUD web app, nor for quasi-exploratory data pipelines, which is where IMO such generic functional combinators are clutch. It is however awesome when you've nailed down the data pipeline and you want to get a big speed improvement in a fraction of the time required to build out in C/C++.

-----

Buttons840 66 days ago | link

What makes Go a good "systems language"? Is it because it's fast? What about Java, Scala, Clojure, Haskell, C#, F#, Scheme, Ocaml, etc, which all have performance (speed of execution) similar to Go, are they good "systems languages" as well?

If it's not speed of execution then what makes Go a good systems language? The ability to fiddle bits? A small runtime?

-----

amalag 66 days ago | link

One thing is gochannels and the lightweight concurrency primitives.

-----

codygman 66 days ago | link

Java, Scala, Clojure, Haskell, C#, F#, Scheme (do Rackets Places count?) all have their equivalents.

-----

ghayes 66 days ago | link

I would use it for a CRUD app and I wish it had features that would support that. As an open-language, this input should be considered (alongside the input of the maintainers and other users of the language). I believe the top-comment here was saying that this conversation shouldn't be side-lined.

-----

voidlogic 66 days ago | link

>The story is, a variety of complex programs are being built and deployed in Golang without generics, which makes it an open question as to whether they're required at all.

This. The same can be said for C as well, but C is not memory safe and Go is- so it wasn't immediately obvious the same would hold for Go.

I used to use generics/templates in Java/C#/C++ a lot, and at first I missed them in Go, but now, after writing Go full time for 2+ years- I no longer miss them more than once or twice every few months... I think generics are great, but also greatly overused.

-----

AlisdairO 66 days ago | link

I work with some old Java code that's a mix of generic-ised and not. Every time I see a method that returns a Collection I want to shout "COLLECTION OF WHAT?!?!".

Comprehending other people's non-generic code is a giant pain in the ass compared to reading code with generics.

-----

wreegab 66 days ago | link

> Every time I see a method that returns a Collection I want to shout "COLLECTION OF WHAT?!?!"

The method was named something like "getCollectionOfSomething()"? If so, you might want to put some of the blame on the method naming choices.

-----

AlisdairO 66 days ago | link

A method might return, say, some URIs. These might be represented as URI objects or strings, depending on your preference (in some tighter areas of the code we might use String objects, because URIs can be expensive-ish to create, and we might know for sure that the strings in question are valid). If I have a method called getURIs, does it return URIs or Strings? Should the method be called getURIsAsStrings? Perhaps, but it makes for some pretty awkward (and long) method names.

Even if you do have a sensible naming scheme that makes the return type clear, it's rather beside the point. If I have a choice between relying on coding convention or generics, I know what option I'm going to pick.

-----

jbert 66 days ago | link

I'm not arguing the point that generics are unuseful.

But imho the method should not be named for the compiler-type of it's return value (unless it's a type converter like int2string or similar).

It should be named for the bizlogic/semantic type:

So..not "getURIs()", but better "getBackendPoolMembers()" or "getBackendPoolMemberURIs()" if you have more than one way of representing them.

Long method names are fine. Everyone uses autocomplete. Choose good names and rename them often as the meaning of the code changes over time.

-----

AlisdairO 65 days ago | link

That's fair enough - I'm always happy to have descriptive methods names. I still want to know the compiler type of what I'm getting back though.

-----

Locke1689 66 days ago | link

Naming conventions are often used as (IMHO) poor substitutions for type systems. A name is for the programmer. A type is for the computer AND the programmer.

-----

collinvandyck76 66 days ago | link

Generics notwithstanding, Go's slices are typed.

var stuff []MyType

-----

justinsb 66 days ago | link

Genuinely interested: do you have a trick for making sorting a collection less copy-and-pasty?

-----

voidlogic 66 days ago | link

I made a bash script for this purpose, but I have actually only used it twice to be honest.

-----

sandGorgon 66 days ago | link

could you elaborate - what is this about ? Go newbie here.

-----

justinsb 66 days ago | link

To sort an array/collection in Go, you must implement an interface with 3 methods: https://gobyexample.com/sorting-by-functions

It's boilerplate, which generic methods would avoid.

There are shortcuts for sorting common types by their natural order in Go, so you only have to write this for custom types or custom orderings.

-----

riffraff 66 days ago | link

I am not sure I understand why you need generics for this, doesn't C get by passing a single function pointer?

Could you explain why Go needs an interface with 3 methods?

-----

pcwalton 66 days ago | link

Type safety, and the lack of fields in interfaces. In C you have to pass the size of the elements to quicksort, but in Go you can't do that without using the unsafe module. So you need a virtual Swap() method. And because Go needs to take a single interface, and interfaces in Go can't have fields, you need a Len() method as well.

-----

riffraff 66 days ago | link

thanks I think I understand now.

-----

Pxtl 66 days ago | link

C precompiler macros can be (and are) used to provide generic-like semantics.

Go has no such "blessed" precompiler-macro system.

Templates/macros are an ugly solution, but they are a solution.

-----

georgemcbay 66 days ago | link

The simplicity of Go's syntax makes it really easy to use as a target for compile-time generated code, and all of the built-in parsing libraries in the standard lib make it really easy to interface such generated code with human-generated code and at the end of all of this you end up with something much more type-safe than you do with C macros.

So yeah, the toolset may not have anything like the C's preprocessor (the lack of which is a blessing, not a curse, IMO), but that's fine, if you're sure you really need such a thing just spend half a day writing your own in Go that is specific to your project's needs and make that a part of your local build process.

-----

Pxtl 66 days ago | link

Are there any good examples of this kind of approach? Any tooling support for this?

-----

georgemcbay 66 days ago | link

None that is publicly available that I'm aware of, unfortunately.

No real tooling either other than whatever you choose to use for the build process. For the projects I've done this for that ends up being a very simple Makefile which does a 'go run' on the code generation engine code prior to a 'go build' of the resulting combined package of generated & hand-written code.

-----

Matrixik 66 days ago | link

Do you use some custom code generation engine or gen[1]?

[1] http://clipperhouse.github.io/gen/ ("A library for bringing generics-like functionality to Go")

-----

georgemcbay 66 days ago | link

Custom -- most of the code generation I've done has been about binding Go functionality into UI markup languages (similar to the way ActionScript binding in Flex works, for those who have used that) as opposed to generics-like functionality.

I've never used gen, it looks pretty nice though, at least based on the linked docs and it is probably a good answer to Pxtl's question about publicly available examples.

-----

mjn 66 days ago | link

> macros are an ugly solution, but they are a solution

Tangential, but a decent example of that sort of thing, a generic red-black tree written entirely in the C preprocessor: http://www.canonware.com/download/rb/rb_newer/rb.h

-----

lflux 66 days ago | link

queue.h is pretty widely used as well: http://www.openbsd.org/cgi-bin/cvsweb/src/sys/sys/queue.h?re...

-----

stcredzero 66 days ago | link

great, but also greatly overused.

This should be a book or a blog. Seems like the most powerful features of languages are often the downfall of a project. Proxies based on #doesNotUnderstand: or method_missing can be awesome and they can also be misused to render a project incomprehensible. The same goes for macros in C, macros in Lisp, and generics.

-----

threeseed 66 days ago | link

Couldn't disagree more with this.

Generics makes code far more readable, maintainable and testable.

-----

AlisdairO 66 days ago | link

Go seems to be picking up a lot of python/rubyists who are looking for a faster language that's not excessively verbose. I suspect that fraction of the community doesn't miss generics as a result of simply never having had them.

-----

Pxtl 66 days ago | link

Dynamically-typed languages don't need generics just like they don't need interfaces. If everything is a duck and everything holds ducks, then you don't need generics.

The need for generics (or macro/template-based equivalents) naturally falls out of using a statically-typed language.

-----

AlisdairO 66 days ago | link

Disagree. Generics aren't just used to enable generic operations - they also provide clarity/documentation on what types are being passed around. As someone who spends a lot of time working on other people's (sometimes old and crufty) code, I find that invaluable.

-----

bad_user 66 days ago | link

That doesn't sound right. Take a look at the Enumerable trait in Ruby and tell me how many of those methods are expressible in Go: http://ruby-doc.org/core-2.1.0/Enumerable.html

I thought the whole point of picking a language like Ruby was to use a language in which you can describe what you want, instead of how you want it.

-----

dpritchett 66 days ago | link

I'm a Rubyist who likes to play with Go.

Boy oh boy do I ever miss collection-level constructs like map and reduce in Go. I just don't think of them as 'generics' because I'm not very well-versed in statically typed languages.

I still bite the bullet and use Go anyway when it feels appropriate, because I can get fast type-checked programs with a reasonably quick prototyping cycle.

-----

codygman 66 days ago | link

This is the reason that Go drove me to Haskell. These days I have fast type-checked programs with a more than reasonably quick prototyping cycle.

Plus after you get types down well enough, you can largely pretend you are using a dynamic language. For instance sometimes I write my functions, make sure they work right, check the type ghci says they are in the repl, and add the type annotation.

-----

AlisdairO 66 days ago | link

I think the amount of time I spend working on Other People's Stuff probably influenced my comment there. While I obviously use and appreciate generics for their enabling of generic operations, I tend to primarily love them for their documenting/strictness-enforcing aspects.

-----

coldtea 66 days ago | link

>There is a story about generics in Go. The story is, a variety of complex programs are being built and deployed in Golang without generics, which makes it an open question as to whether they're required at all.

The same argument could be used against adding closures to Java. After all "complex programs are being built and deployed without them". And yet, everyone thinks that it's a good idea that should have happened years before.

I think the argument is a variation of "I can do stuff in assembly just fine, why I'd need a higher level language?".

>Golang doesn't have to be all things to all people, nor does it have to fulfill every programming task any one developer has.

Well, generics are pretty basic to talk about having them as "being all things to all people". It's not like the majority of users testing or using Go regularly ask for all kinds of exotic features. The vast majority, judging from the mailing list, blog posts, articles etc, just have this major gripe.

-----

MrBuddyCasino 66 days ago | link

A variety of complex programs are being built and deployed in plain C without generics, which makes it an open question as to whether they're required at all.

-----

sdegutis 66 days ago | link

> a variety of complex programs are being built and deployed in Golang without generics, which makes it an open question as to whether they're required at all.

Similarly, a variety of complex programs are being built and deployed in [any other language] without Go, which makes it an open question as to whether Go is required at all.

My point isn't that Go isn't needed. It's that this argument against generics in Go is hypocritical and contradictory to the whole reason Go exists.

-----

justinsb 66 days ago | link

I totally agree; I've "gone off Go" until they figure out (1) errors vs exceptions, and (2) generics. I have no problem with them saying "we're not Going there", but if so I wish they would at least say that. Right now, I'm betting at least one of those positions will change, and it will have fairly big ramifications for any existing code (in the same way that Java 1.0 code still runs, but is rather different code).

-----

tptacek 66 days ago | link

I don't think they're "figuring out" exceptions; my understanding is, they're not going to happen.

I am also not a fan of hyperliteral case-by-case error checking (it reminds me of my early C code), but it's A Style, one that the Golang team enthusiastically adopts, and it's unlikely to go anywhere.

-----

voidlogic 66 days ago | link

Go's returned error allows very varied error handling if wanted/needed: http://play.golang.org/p/-2q6N08x_P

More than just the normally used: if err := foo(); err != nil; { return err }

Large code Go code basis are so much better (more maintainable) for "hyperliteral case-by-case error checking". My impression that only people who havn't written large Go projects have this complaint.

Also, there is no reason you could not define a function like:

  func foobar() (fatalErr, err error)

-----

tptacek 66 days ago | link

I'm not sure how that code example demonstrates something other than error checking that has to be written case by case at the call site of any function that might return an error.

-----

voidlogic 66 days ago | link

Well it does demonstrate that, and I think that is a good attribute of Go. (And if the caller returned the error, it could be handled by a previous caller too btw)

What I was showing was that:

  try {
   foo()
  } catch (ex1 ExType1) {
   ...
  } catch (ex2 ExType2) {
   ...
  } catch (ex ExBaseType) {
   ...
  }
Type logic is completely possible, which while apparent to you is lost on some people who haven't work with non exception langs before.

-----

jamwt 66 days ago | link

Not if you want to parameterize the exceptions. This kind of "matching" requires that you compare your exception "types" by exception "values", so you cannot provide parameterized information about what exactly failed.... which key? Which URL?

Underpowered error handling (and I'm not advocating for exceptions, persay), lack of generics (and the resultant copypasta party and interface{} runtime casting [aka, the return of void *]) are real warts in an otherwise fine language.

And I'm not just theorizing: I spend my days writing a large, nontrivial system in go.

I've used Haskell a lot before, and I'm not asking for no nulls or real ADTs (though I wouldn't complain), but generics + better typed errors would really help clean things up.

Meanwhile, a lot of us are just waiting for rust...

-----

beatgammit 66 days ago | link

Maybe I'm missing something, but you can do this with a type switch: http://play.golang.org/p/jF_bPQdwxk

It just depends on what you're trying to accomplish, but most use-cases can be accomplished without exceptions. The other use-cases often indicate bad design.

As for generics, you can get 90% of the way there with interfaces. The use of `interface{}`--while sometimes necessary--is often an indicator of bad design.

In large code bases, you often don't need (or care) to know what underlying type something is. For example, you shouldn't care whether an `io.Reader` is a TCP socket, file or completely in-memory ala `io.Pipe()`.

There are times when type assertions are the best/only way to get something done, and that's why they're there, but those cases should be relatively infrequent.

Generics would make some things easier (Rust's implementation is quite nice), but it's not significantly impacting my productivity, and I certainly wouldn't consider switching languages just because Go lacks them.

EDIT: Added info about generics

-----

4ad 66 days ago | link

Of course you can, error is an interface, any number of concrete types can satisfy it, and you can use type assertions or type switches to unbox (and use) that concrete type.

This is a widely used idiom in Go.

-----

azernik 66 days ago | link

Errors in Go are custom types; your error can be defined as, for example:

    type URLError {
        url String
    }

    func (e URLError) Error() String {
        return fmt.Sprintf("Invalid URL: %s", e.url)
    }
At which point a caller that wants to handle this error can either extract the URL to do fun things with it or just dump the Error() string.

-----

bad_user 66 days ago | link

That seems to me like an awful example. But speaking of generics, exceptions and other things that Go lacks, like pattern matching, lazy values, currying and so on, in my opinion Go sucks because you can't abstract well over common patterns. To take your example as a use-case:

    object NonFatalError {
      def unapply(err: Throwable) = err match {
        case _: TimeoutException => Some(err)
        case _: IOException => Some(err)
        case _ => None
      }
    }

    def executeWithRetries[T](maxTries: Int)(callback: => T): T = 
      try {
        callback
      } 
      catch {
        case NonFatalError(error) if maxTries > 0 =>
          logger.warn(error)
          executeWithRetries(maxTries - 1)(callback)
        case other: Throwable =>
          throw other
      }
And usage:

    def funcMayErr(): Int = throw new TimeoutException

    val value = executeWithRetries(5) {
      funcMayErr()
    }
But there's more. Because with generics and exceptions you can actually wrap the whole result in an algebraic data-type that also has handy methods for dealing with failure (e.g. a monad), as in:

    Try(executeWithRetries(5)(funcMayErr)).map(x => x + 1).getOrElse(default)
Cheers,

-----

ithkuil 65 days ago | link

There are 3 kinds of people that read code:

* those casually glancing over to figure what the code does * those actually trying to figure out what a given expression does, either because they are reviewing or debugging * compilers are people too

Conciseness is often overvalued and pursued to the extreme where effort is made first by the author to seek for the perfect oneliner, and then for the reader to actually check that this code is doing what expected.

Composition is important, but I don't think I found great real world examples of composition which wasn't either working only because of a tightly controlled code base or because it was just an example to prove a point.

Don't get me wrong, I love scala/haskell, I find playing with those constructs interesting and beautiful.

It's just that Go is a different thing, is a modern approach of getting back to basics, a minimal toolset for do just programming, more or less translation of thought into instructions.

And it's works very well; it's very easy to get things done quickly and the produced code tends to be easily maintainable. It's easy to have control over the memory footprint. The tooling is very mature (http://blog.golang.org/race-detector, gofmt formatting+refactoring)

-----

enneff 66 days ago | link

You just don't know Go if you think it "can't abstract well over common patterns".

-----

coldtea 66 days ago | link

Well it can't. Take for example "sort", "map", "filter" etc.

That it can abstract some other "common patterns" doesn't solve this.

-----

reyan 66 days ago | link

I think many of us want Go to be something it doesn't want to and will never be. There is potential for a fast, simple, statically typed language; borrowing good ideas from Lisp, ML and others (and NOT resulting in something like Scala).

-----

voidlogic 66 days ago | link

func execWithRetries(f func() error, retryc int) error

can easily be implemented in Go: http://play.golang.org/p/kMNqfY7LYX

-----

justinsb 66 days ago | link

Exceptions are already in the language: panic/recover. Though discouraged, you can't assume they won't happen. To me, this seems like the "worst of both worlds". It doesn't feel like a final position to me, it feels like a 1.0 position.

-----

tptacek 66 days ago | link

You can abuse "panic" to implement exceptions in Golang the way you can abuse "longjmp" to do that in C. The purpose of "panic" isn't for general-purpose exceptions. It's to panic the program.

-----

justinsb 66 days ago | link

It's clear you shouldn't throw.

But correct code must assume that any function you call might throw; which is why you should use defer blocks e.g. to release resources, instead of C-style "cleanup at the bottom of the function". (Defer is also prettier IMHO)

-----

tptacek 66 days ago | link

You're not "throwing". You're "panicking".

-----

ithkuil 65 days ago | link

Or raising? That's just terminology. The behaviors of c++/java/python exceptions and Go panics are similar regardless of the name the keyword has in those language:

The execution is suspended, the stack unwound until the first handler, the handler has access to a value that is "thrown". Stack information is preserved in order to print meaningful stack traces.

C++/java/python have syntax sugar that performs a pattern match on the thrown object to decide whether to handle it or bubble it up, while in Go you do it manually, but other that that I don't see much of a difference in the mechanics of them to justify being so pedantic about the naming of the action.

-----

JulianMorrison 66 days ago | link

It's idiomatically correct to ignore panics and let them take the whole program down with a crash. A panic indicates that your program is already doing extremely incorrect things. Rare is the program where picking itself up and continuing a possible Sorcerer's Apprentice mode rampage is better than just stopping and telling you what needs fixing.

-----

mjibson 66 days ago | link

Note that this mechanic is used in the golang standard library and works great as a catchall: http://golang.org/src/pkg/text/template/exec.go#L93

-----

mratzloff 66 days ago | link

But panics are not exceptions. They should not be used like exceptions, and there is no "hierarchy of panic types".

They are used for things like out of bounds indexes, where in C it would simply be a segfault. A panic is a way of gracefully exiting a program that would have segfaulted otherwise. Correct code should check for out of bound indexes either way.

-----

georgemcbay 66 days ago | link

I agree, but would also point out that panic isn't necessarily going to exit a program, recover exists and it isn't that uncommon for programs or libraries to do a deferred recover at the beginning of goroutines so that a panic within that goroutine will only kill off that goroutine and allow the main goroutine and other goroutines to continue.

Of course this "pattern" should only be used when you're sure that that one failing goroutine won't have a cascading impact on other goroutines that are still running.

-----

pcwalton 66 days ago | link

Not all exception systems have type hierarchies. Neither ML nor Haskell have inheritance and both have exceptions.

-----

ben0x539 66 days ago | link

Haskell exceptions form a hierachy though.

-----

justinsb 66 days ago | link

I think I've answered this elsewhere: the issue for me is that you have to handle exceptions _and_ error codes.

Though you raise an interesting point: Should you check array indexes if the runtime is also checking it for you?

In Java, the runtime is guaranteed to throw an exception and it is relatively rare that you would pre-check the array indexes (you might use assertions in debug code).

Incidentally, array bounds checking is actually relatively expensive, to the point where most JVMs (which use signed indexes) use an unsigned comparison trick to make it one comparison instead of two. So it does matter...

-----

redbad 66 days ago | link

If you're recovering from panics, in general, you're doing something wrong.

-----

enneff 66 days ago | link

> the issue for me is that you have to handle exceptions _and_ error codes.

Except you don't. I haven't used recover in any of my code for a long time (more than a year). Most of the time you don't need to worry about handling panics, but you can if you really need to.

> Should you check array indexes if the runtime is also checking it for you?

In Go the generated code does it. You shouldn't do it yourself.

-----

justinsb 66 days ago | link

I consider defer to be part of handling exceptions, but I can see how we differ here.

We're seriously drifting off track here, but if we should rely on Go to check array indexes, that seems like you _would_ want a recover block, so that we can map it to a Go-preferred error code?

-----

enneff 66 days ago | link

Go doesn't have exceptions. Can you please stop saying it does? There's a reason we didn't give "panic" the name "throw". Because they work differently and are used for different things.

There's also no such thing as a "recover block" (you're thinking of a "finally block" or "catch block", neither of which exist in Go).

If we thought you should use recover any time there might be an array out of bounds panic, we'd have designed the whole language differently. Panics should happen when things go badly wrong, and most of the time that means your program should crash.

You should use recover only in two rare cases: 1. where you're specifically using panic/recover as a kind of setjmp/longjmp (as it is used within encoding/json, for example), and 2. where you don't want a programming error to bring down your entire program, such as in the base net/http handler (although I think it's debatable whether we should have done it there; but it's done now and we can't change it).

It amazes me that there has been so much discussion over this incredibly minor and seldom-used feature. Just return and check errors (and just panic when things go really wrong) and get on with your life.

-----

collinvandyck76 66 days ago | link

Doesn't the http package's Server recover from panics in the goroutines that are created to serve requests? That bugged me when I saw it happen. If my request handler panics, I wouldn't expect the server to recover from it.

-----

joncooper 66 days ago | link

The point is that an exception in Go world means: something which should not ever happen, and which renders continued execution impossible. IMO recover should only be used to wind down execution in as graceful a manner a possible prior to terminating the program.

As opposed to an error, which can and will happen.

-----

aaronblohowiak 66 days ago | link

we should rename recover to "log this before terminating the process"

-----

gnuvince 66 days ago | link

Here's what's going to happen: neither parametric polymorphism, nor exceptions are going to happen in Go. The answer in the FAQ is just PR bullshit; the designers of Go are not interested in having parametric polymorphism and that's the bottom line.

-----

4ad 66 days ago | link

FWIW, Limbo, Go's ancestor from the same author, does have generics.

-----

enneff 66 days ago | link

You can say that until you're blue in the face, but the fact is we continue to discuss generics to this day and are very much interested in including them in the language.

Why do people keep ignoring me when I say this? I guess the idea that the Go team are a bunch of generics-hating curmudgeons is more compelling than the reality.

-----

codygman 66 days ago | link

Perhaps you should blog about "Generics in Go discussions"? Then you would have some proof and dispel mistruths about Go. I would also get excited, since reality seems like Go developers don't care that much about generics.

However, I'm taking into account you said that they do :)

-----

enneff 66 days ago | link

Such a blog post would be a lot of effort and detract from the many other important things we have going on.

-----

frowaway001 65 days ago | link

Then you should stop complaining that people consider you liars. :-)

-----

codygman 66 days ago | link

Understandable. Only you can decide whether focusing on those other things or a blog post like that is more important.

I don't blame you for not writing it up, I don't think I would either ;)

-----

andybalholm 66 days ago | link

Probably because a lot of Go users _are_ generics-hating curmudgeons :-) (even though the team aren't)

-----

joncooper 66 days ago | link

What is there to figure out about errors vs exceptions? I think the Go position on that matter is very clear.

-----

justinsb 66 days ago | link

As I understand it, the position is that there are error return codes _and_ exceptions. Error return codes are for bad stuff, Exceptions are for really bad stuff. So correct Go code pays the price twice: it should be exception-safe, _and_ you have to manually handle error codes.

-----

tptacek 66 days ago | link

Golang does not have exceptions. It has "panic", which, you can see from the name, is meant to end a program's execution and is presumably "recoverable" only so that programs can wind themselves down (more) gracefully.

-----

justinsb 66 days ago | link

You say panic, I say exception :-)

My concern is not nomenclature, but that correct code must handle paniceptions. And that it must also handle return value errors. Go code IMHO ends up spending a lot of code on error handling, I think because of this double taxation.

-----

tptacek 66 days ago | link

You say "setjmp", I say "thread library".

-----

pcwalton 66 days ago | link

I think you're misunderstanding justinsb's point a little bit. To be concrete, you have to remember to use "defer" in Go to clean up resources and locks, or else someone trying to use "recover" won't handle panics properly.

This won't unlock the mutex on panic, which is observable if someone is trying to recover():

    func F() {
        mutex.Lock()
        ... do something here that panics ...
        mutex.Unlock()
    }
But this will:

    func F() {
        mutex.Lock()
        defer mutex.Unlock()
        ... do something here that panics ...
    }
This is basically the same set of hazards as maintaining exception-safety in C++ or Java. So in this regard panic is very much like an exception system. (Of course, it has very different idiomatic use.)

-----

beatgammit 66 days ago | link

Best practices for try/catch may be similar to idiomatic defer, but it's not the same semantically. For example, there's no analog to this:

    try {
        ... do something that throws ...
    } catch (...) {
        ... deferred code
    }

    ... other code
If you don't use `catch`, then I could agree that try/finally is the same as defer, but I would argue that defer is a much cleaner design since cleanup code is located next to the thing they're cleaning up.

I think it's much easier to audit this:

    mutex.Lock()
    defer mutex.Unlock()
Than this:

    mutex.Lock()
    try {
        ... code that panics
    } finally {
        mutex.Unlock()
    }
Other languages also make a distinction here, for example Python's `with` and D's `scope` [1].

Also, it's trivial to make a `panic` that is unrecoverable: `go panic("broke your code, lol!!")`. This just cements the idea that `panic` is semantically different than exceptions, and should be treated as such.

[1] - http://dlang.org/statement.html#ScopeGuardStatement

-----

pcwalton 66 days ago | link

> Best practices for try/catch may be similar to idiomatic defer, but it's not the same semantically. For example, there's no analog to this:

You can do that by creating another function.

> Also, it's trivial to make a `panic` that is unrecoverable: `go panic("broke your code, lol!!")`. This just cements the idea that `panic` is semantically different than exceptions.

That's not different. In, say, Java, you can set the default uncaught exception handler to get the same behavior and then you can write:

    new Thread() { throw new RuntimeException("..."); }

-----

beatgammit 66 days ago | link

> You can do that by creating another function.

You can't emulate the behavior of continuing the current block after an exception is caught. You have to recover() and copy/extract into a function any code that you'd want to run in the recover.

For example:

    try {
        ... code that throws
    } catch {
    }
    ... other code
In Go, to run "other code", you'd have to duplicate all of that logic in the recover():

    defer func() {
        if err := recover(); err != nil {
            ... other code (duplicated from below)
        }
    }()
    ... code that panics
    ... other code
This isn't really the same thing, but I suppose you could technically get the same effect if you move all of "other code" into a function and called that in both places, but you're still duplicating code.

Panics and exceptions are two very different things, which is why there are different idioms in place to make working with them safe.

-----

pcwalton 66 days ago | link

> This isn't really the same thing, but I suppose you could technically get the same effect if you move all of "other code" into a function and called that in both places, but you're still duplicating code.

Right. It's a pretty trivial transformation, and that's why it's not inaccurate to call panic/recover equivalent to exceptions: you can straightforwardly express every exception-based pattern using defer/panic/recover, and also the other way round. Sometimes you have to make more functions to make panic/recover work, but that's part of the "tied in with function declarations" nature of panic/recover/defer—there's nothing semantically that deep about it because the transformation is still quite simple.

-----

beatgammit 65 days ago | link

I suppose that's technically true, so I'll have to concede the point. However, I still maintain that it's not practically true, since it has a very different flow than exceptions.

Anyway, I assume you're the same pcwalton from Rust? I really like the design of error handling so far, especially the bit about trapping conditions. From what I read, it looks failure just kills the task, instead of the entire program (like it does in go if unhandled).

I'm really looking forward to 1.0. Keep up the good work!

-----

ansible 66 days ago | link

... To be concrete, you have to remember to use "defer" in Go to clean up resources and locks, ...

You should probably be using defer() all the time anyway, unless you have a good reason not to. It also helps with code evolution, in the cases where some yahoo adds a new return statement in the middle of a function.

-----

mseepgood 66 days ago | link

> My concern is not nomenclature, but that correct code must handle paniceptions

No, correct code doesn't have to handle panics. Panics are for programming mistakes.

-----

jerf 66 days ago | link

I am writing a server which will maintain thousands of SSL-encrypted simultaneous connections for a real-time application. If ONE panic makes its way to the top of the relevant goroutine, the whole process comes down, trashing all my connections in the process. It is non-trivial to reestablish them. Yes, my system is built to handle this case, but it's still not something I can afford to have happen every 15 seconds due to some error that is only affecting one out of my thousands of connections. (Also, I do understand why this is the only choice the Go runtime can make; this is not a complaint.)

At least in my world, every time I type "go", I must ensure that I am starting a goroutine that has some sensible top-level recover mechanism, and, honestly, for any Go program that actually plans on using concurrency, I think there's no alternative. You MUST handle panics. Why? Because an important aspect of Go's concurrency is maintaining composition of independent processes, and there are few things more uncompositional as a completely unrelated computation in a completely unrelated thread that trashes your entire OS process.

Panics may be for programming mistakes, but for any non-trivial code, you have some. Hopefully you can work out a better way of handling them than completely bringing the entire program down.

I am willing to assert that my code maintains enough isolation that continuing on is a reasonable thing to do. (It's a port of Erlang code anyhow. This is not a very freaky claim about such code.)

-----

justinsb 66 days ago | link

Sadly, you do, but Go makes it tolerable with "defer". Defer also produces nicer code.

Without defer, to be correct you would have to explicitly 'recover' (and re-panic?)

-----

redbad 66 days ago | link

No, you don't. You should never be using recover as a matter of course.

You seem really hung-up on this point. Can you link to some code that illustrates your concerns?

-----

burntsushi 66 days ago | link

That's just not true. There are very useful idioms for panic/recover, like when your code is profligate with errors (parsing, database work, etc.)

It's even used in the standard library: http://golang.org/src/pkg/text/template/exec.go#L93

(I use the pattern myself in certain situations. It's extremely useful.)

-----

redbad 66 days ago | link

Note I said "as a matter of course". I agree it's useful in certain very limited circumstances, like parsing. But certainly not database work, unless you have a very different idea of what that entails than I do. Link to code?

-----

burntsushi 66 days ago | link

It's the same principle as parsing. Database work involves lots of querying, scanning, etc. All of these operations produce errors. In the work that I do, the response to an error is usually, "rollback, show error to user." This makes it ideal for panic/recover. (And this can work well for either command line applications or web applications.)

-----

vertex-four 66 days ago | link

Panicking isn't done when a database operation fails. Returning an error value is. It's just like old-school C. Panics are for programming errors or things like out of memory conditions, not errors in ordinary operation, even when components are failing.

-----

beatgammit 66 days ago | link

Exactly.

I have exactly two panics in my ~15k line server. Both are in initialization code that will probably never get called, so it will fail very early on in the code. The rest of my code looks like this:

    func getRecord(args...) (err error) {
        if err := doSomethingRisky(); err != nil {
            return err
        }
        if err := doSomethingElseRisky(); err != nil {
            return err
        }
        ... other code ...
        return nil
    }

    func processRecord() error {
        if err := getRecord(args...); err != nil {
            return err
        }
        ... do other stuff ...
        return nil
    }
All the way down the stack. It's certainly a little more code, but it forces you to at least acknowledge all errors. If you want a stack-trace, you can always use the runtime package.

-----

burntsushi 66 days ago | link

No, this isn't what I'm talking about. See my response: https://news.ycombinator.com/item?id=7222197

-----

burntsushi 66 days ago | link

I hate to be rude, but I feel like you jumped into this thread without reading the context.

I'm not talking about panicing instead of returning errors. I'm talking about using an idiom---which is used in the Go standard library (see my link up-thread)---to make error handling more terse when you're working with code that is otherwise profligate with checking errors.

At no point is a panic exposed to the user of a program or to the client of a library. At no point are errors ignored. The panics are kept within package and converted to error values.

-----

redbad 65 days ago | link

Guarding your library boundary with a recover doesn't absolve your library internals from being nonidiomatic by using panics. (That the stdlib uses panic/recover in a few specific places does not make it broadly idiomatic.)

Without seeing specific code I can't say for sure, but it's very unlikely that any database interaction code is best modeled with panic/recover for error handling. I'm very curious to see the source, at this point.

-----

burntsushi 65 days ago | link

> Guarding your library boundary with a recover doesn't absolve your library internals from being nonidiomatic by using panics.

Using panic/recover doesn't automatically make your code nonidiomatic.

> (That the stdlib uses panic/recover in a few specific places does not make it broadly idiomatic.)

That the stdlib uses panic/recover in several places is a good indicator that "never use panic/recover" is bad advice. Note that while I agree that just because something is in the stdlib doesn't mean it's idiomatic, I also cite that this particular approach is used to make the structure and organization of code more clear. Since it's used in several packages, I claim that this is a strong hint that panic/recover is appropriate in limited scenarios.

> Without seeing specific code I can't say for sure, but it's very unlikely that any database interaction code is best modeled with panic/recover for error handling. I'm very curious to see the source, at this point.

It's really not that hard to imagine. For example: http://play.golang.org/p/fhpRLd8EHY

We seem to have some wires crossed. Let's be clear, shall we?

* The panic/recover idiom is rarely used, but it is an idiom.

* There are trade-offs involved with using panic/recover. In my sample linked in this comment, many of the functions in database/sql need to be stubbed out so that they panic. However, the cost of this is relatively small, since it can mostly be isolated in a package.

* The idiom is most frequently seen in parsing because there are a lot of error cases to handle and the response to each error is typically the same.

* While parsing is the common scenario, I claim it is not the only one. I cite that database work is profligate with error checking, and depending on your application, there's a reasonable chance that the response to each error is going to be the same. When doing a lot of it, it can pay off to use the panic/recover idiom with similar benefits as for doing it with parsing.

* There may well be other scenarios where such handling is appropriate, but I have not come across them.

I've done an unusual amount of work with parsers and have done some database work, so I've had the opportunity to bump up against the panic/recover idiom a bit more than normal. As with anything else, it can be abused. But I find it extraordinarily useful in certain situations.

-----

burntsushi 65 days ago | link

I've fixed some compile errors in my code snippet: http://play.golang.org/p/PLyMAD5ZvG --- sorry about that.

-----

waps 66 days ago | link

This is just another example of Go's fundamental attitude. Stuff is available for the language designers, but not for you :

* generic functions (e.g. append)

* generic data types (e.g. slices)

* exceptions (like illustrated above)

* special case syntax

* Custom event loops

* precompiler macros (very bad to use, horrible, blah blah ... except of course for the people imposing this restriction, and YES they're using it amongst other things to workaround the lack of generics in C)

...

This attitude was common in middle-90s "generic" programming languages like Ocaml, Modula-2 and others. You should simply look at Go as one of those languages and treat it as such.

If this attitude bothers you, you should look at C++0x and D.

-----

burntsushi 65 days ago | link

I've read your comment twice and I cannot see any pertinent connection between it and what I said.

-----

justinsb 66 days ago | link

Agreed, you should be using defer, not recover.

The canonical examples are closing a file and releasing a mutex. Both have code samples here: http://blog.golang.org/defer-panic-and-recover

I'm confused as to what you guys are saying: are you saying that you don't need to handle exceptions (whether using defer or recover), or that it's better to use defer over recover? I take exception to the former, totally agree with the latter.

-----

enneff 66 days ago | link

defer doesn't "handle" panics. It won't stop your program from crashing. You have serious gaps in your knowledge on this subject.

-----

justinsb 66 days ago | link

My understanding is that defer is the broad equivalent of a Java finally block, and recover is the broad equivalent of a Java catch block. I think of both as ways of handling exceptions, although I see how the word "handle" could be interpreted in a way that makes my statements nonsensical. By handling I meant "doing the right thing", not "swallowing the panic/exception"; I apologize for the ambiguity you found.

If you do still think I have gaps in my knowledge, I humbly suggest that you briefly fill in those gaps with facts; it should save you time in the long run and will likely win you a few converts!

-----

enneff 66 days ago | link

You're looking at it wrong. Stop thinking about Java. Go programmers rarely use recover. There are many that have probably never used it at all. Go does not have exceptions. Panics are only vaguely like exceptions, but you shouldn't even think about them in those terms. It is confusing you badly.

Defer is primarily used to make sure that clean-up happens in functions that have multiple exit points (return statements). It's a convenient side effect that defers are executed while a panic unwinds the stack, but it is rarely the first thing on the mind of the Go programmer when they type "defer".

Embrace error values. Return them! Check them! Panic when shit goes really bad. That's it. If you're writing Go code and you're thinking about "throw" "catch" or "finally", you're doing it wrong. Go's features do not map cleanly to those concepts, because Go doesn't have exceptions.

-----

redbad 66 days ago | link

defer and recover have nothing to do with each other, except that in the few circumstances where it's appropriate to use recover, you often do it within a defer block.

    > are you saying that you don't need to handle exceptions 
    > (whether using defer or recover)
Go doesn't have exceptions. You don't need to handle (i.e. explicitly deal with) panics via recover. If you do, especially if you're not making the panics yourself in e.g. a parsing package, that's a bad code smell and you're probably doing something wrong.

-----

enneff 66 days ago | link

We're still talking about generics. It might be sooner than 2.0. We have already said this several times.

-----

RamiK 66 days ago | link

Before Generics, the Garbage Collector needs to be sorted out since that's what dictates the optimizations and abstractions in the rest of the safe code in a very significant way. e.g. Simple scope issues like "Do I allocate this array now, or inside the for loop" were still a question of Go 1.1 vs. Go 1.2...

Then, once the GC is decided and realized, wouldn't you rather have Go self-compile so that the community could sprout experimental branches to test out different Generics approaches and designs? Especially since the Gophers themselves aren't too sure about the right approach here and want to get as much feedback as they can...

TL;DR: It seems to me that the current trajectory of focusing primarily on the GC and self-compiling is the right way to go.

-----

jksmith 66 days ago | link

This

-----

naner 66 days ago | link

I agree the worst thing about Go is the lack of generics. Not because of the missing functionality, but because you can't talk about go without somebody bringing up generics.

-----

3JPLW 66 days ago | link

Reminds me of the Python GIL.

-----

ithkuil 65 days ago | link

Why?

-----

3JPLW 65 days ago | link

"Not because of the missing functionality, but because you can't talk about go without somebody bringing up [the GIL]."

It's better these days, but for a while it was a common point of contention.

-----

LBarret 65 days ago | link

it was slightly different: Anybody who wanted to try implementing a gil-less python could. The reasons of the status-quo were well explained.

We only get hand-waving from the Go core devs.

-----

ithkuil 65 days ago | link

Adding generics to the language affects the language and reimplementing an interpreter/compiler for a language that fixes a performance issue without being incompatible are two completely different things.

-----

gtaylor 66 days ago | link

My understanding is/was that they'll get around to it eventually, but they're not in a hurry to rush it and stink it up. I haven't missed them too much in my tinkerings.

-----

joncooper 66 days ago | link

The sense I've gotten is that the Go team is surprised how little complaint has arisen among actual Go users about the lack of generics, and that that has kept the priority level low for figuring out how to implement them. In other words it seems like the Go team is actually slightly more interested in having them than the user base is.

I'd like them in part because it'd enable all kinds of delightful reactive functional idioms that just aren't very possible currently. On the other hand I'm accomplishing an awful lot in Go without them..

-----

jerf 66 days ago | link

I don't care too much about the "delightful functional idioms" (on the grounds that merely adding generics to Go will still leave us pretty impoverished on that front anyhow) and doubt the Go team does, either. Probably the biggest and most visible pain point of missing generics is here: http://golang.org/pkg/container/ In particular, the pain point is that there aren't very many things there.

Missing generics does not mean that no alternate data structures ever get written; as you can see, there are three of them there, which is greater than zero. However, it does mean they are more painful to use, consistently, everywhere, and no matter how much we'd all like to pretend we are infinitely disciplined programmers, pain matters, and in practice programmers visibly shy away from harder things. It is simply a fact that we must deal with. Generics missing from the language are a problem because it means that doing the right thing is harder than doing the wrong thing of just, say, using the wrong data structure because it's more convenient. A language (or an API or a library) should make right things easier and wrong things harder; it is a legit criticism when the right thing is impossible and the wrong thing (extensive copy & paste) is the only choice.

Maps & slices are great and all, but they do not correctly cover all use cases, and the sort of servers that Go is otherwise very suitable for is also exactly where you might end up needing something other than those two things for performance reasons.

I'm living without generics in Go, of course, because everyone programming in Go is. But I definitely see a lot of places here and there where I'm writing 5 lines extra, 10 lines extra, here, there, a little bit everywhere, that I simply should not have to write. Or, far worse, debug. Too often in Go I'm copying & pasting code where I should have generics, too often I'm fiddling with data structures at a lower level than I really need to.

-----

jimbokun 66 days ago | link

Interesting, sounds like this could lead to everyone using the built in Go types even where they are not optimal, the way some old Lisp programs modeled everything as lists.

-----

justinsb 66 days ago | link

A sample set of "people that will tolerate the lack of generics" might be slightly biased on this question!

-----

joncooper 66 days ago | link

For sure. On the other hand, one need not forgo an appreciation of fine Bordeaux simply because they enjoy shotgunning Coors Light.

-----

stcredzero 66 days ago | link

True, but then one is more likely to be appreciating the extra effort of a craft brewer who knows how to get the benefit of really lively hops.

-----

DougMerritt 66 days ago | link

> enable all kinds of delightful reactive functional idioms

Link?

-----

joncooper 66 days ago | link

https://www.coursera.org/course/reactive

-----

DougMerritt 66 days ago | link

Gee, an entire course on functional reactive programming rather than a link to the FRP idioms enabled by generics? For me? Gee thanks.

-----

ansible 66 days ago | link

I do definitely want some kind of support for genetics in golang. I do understand and respect the difficulties the principal authors have with integrating it into the language as-is.

There's actually a sort of workaround that I kind of liked:

http://play.golang.org/p/LkVWkyph75

Discussion here:

https://groups.google.com/forum/#!topic/golang-nuts/UyKree3B...

The basic approach is to define most of your generic data structure to use interface {}, and then have type-specific get/put and maybe comparison. This then minimizes the boilerplate code needed while retaining type safety. Implementing the generic functions requires a little more care than usual. But I think it is one of the best approaches for the language currently.

-----

dualogy 66 days ago | link

> but the lack of discussion

I wouldn't say there has been a "lack of discussion" on generics at all..

-----


    >Go is significantly slower than the rest, much much slower.
Everyone knows that Go is a new-ish language and has room to improve on performance. That said, Go seems perfectly fast since all of the languages seem to perform fairly well.

Further, were Go "much much slower", CloudFlare, IronIO, Google, etc would probably not be using it...

    >discover a new interest in D, C or Erlang
    >where performance is a consideration
Erlang on The Game: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...

Go looks to be about ~50% the performance of C++, but, from lots of peoples' comments/writings, is much nicer to write so they use it when productivity is more important than absolute performance.

Note: I'm interested in Go (as I am about lots of languages), but am not a user of it right now.

-----

colanderman 134 days ago | link

Ya, Erlang doesn't do well on the Benchmarks Game because the Benchmarks Game doesn't measure communication, which is Erlang's strong point. No-one writes algorithms like those in the Game in Erlang; you code them as a server in C or Java or anything and farm work out to them from Erlang.

-----

rdtsc 134 days ago | link

> Erlang on The Game: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t....

The Game is a terrible benchmark for Erlang. Math, computing digits if Pi, string searching, n-body problems. If that is the target domain, don't pick Erlang, or Go, pick Fortran or C.

-----

More

Lists | RSS | Bookmarklet | Guidelines | FAQ | DMCA | News News | Feature Requests | Bugs | Y Combinator | Apply | Library

Search: