Hacker News new | past | comments | ask | show | jobs | submit login

The more I dig into type coercion and interfaces the less I miss generics. Still not 100% there, but for day to day the things I used to use generics for have been replaced by alternates. I still wish I never had to write `interface{}` though.

Debugging absolutely needs work though.




Is "alternates" a euphemism for "code duplication?"


Or code generation?


I'm getting furstrated by code generation. I have a big project with has 3 files with (only) generated code. It's essentially repeating the same 15 lines about 50 times with slightly different types.

And yet I far prefer all of them over an interface{} solution. Works so much better. But the files are just so ugly, and changing them is rather hard.

Worst of it all, I've been thinking about generating other pieces of the code. For instance, I hate the http handlers and structure surrounding them being the same thing all the time.

Http handlers = decode and basic argument validation, then authentication and CSRF protection, and then conversion (to be done ad-hoc because no types in http parameters), some using strconv, some using json encoding, all with "error handling" (essentially if error then bailout 502), followed by calling the actual method. All of them are the same (save for small bugs due to me not paying attention).

I'm thinking of replacing it with generated code.


Have you looked at http://goa.design/ which kinda describes what you are talking about a bit (for REST apis).


What are you using generated code with lots of types for out of interest? I haven't felt the need as yet but would like to try it out.

Re handlers, you really don't have to use the http handler. I use one which accepts a context, and returns an error (for rendering), which simplifies the boilerplate somewhat as errors are rendered by the router. I'd look into using your own interfaces before generating standard http handlers.

The other thing to bear in mind is that if you try to make things all implicit rather than explicit in order to avoid repetition, it's very easy to be unaware of what's happening behind the scenes (auto-auth, or auto-render as in rails), and get stuck when you want to do something off the beaten path. I rather like Go's more verbose but very explicit style. It's a trade-off.

Auth, CSRF, parameter parsing should definitely be in a separate pkg you're using, not repeated each time IMO, so there should be minimal boilerplate for those.

Using text template is a really nice way to generate http handlers if you typically set up resources in a similar way, so I'd definitely recommend trying that out. I haven't looked into go generate as that came out after I started this approach.

The approach I take is to generate actions with all the normal code in them as scaffold (for CRUD actions) - so for each one auth, then setup, then business logic, then render, and then edit those as necessary, as often as an app grows each action diverges from the standard (say it doesn't do auth, or processes parameters differently etc). This is easy, explicit, and very clear when returning to code after 6 months at the cost of some verbosity.


> What are you using generated code with lots of types for out of interest

Firstly, for data access methods (think load struct type X from offline storage). It's like gobs or encoding/*, but it blasts those away when it comes to speed.

Secondly, for searching through data (given a list of struct type X, and some number of indexes of the data (essentially listing what the sorting order is according to one of the fields), search for the record that satisfies condition X, fast.

It's very handy that after generation, my vim editor will actually autocomplete all the available methods, and adding an extra method or struct to either the datastore or the in-memory searchable index is adding a line to a file and pressing a shortcut.

And the one I've started to write, given function X with named input params a,b,c and named output params d, e and f, accept an http request extracting these parameters, validating authenticated user, check CSRF, all with appropriate error handling, call function X with the parsed parameters, encode it's outputs as a json struct and return the response. Well, I'm working on this one, I guess, so this one might still change. Maybe also write a javascript interface that calls these methods to a typescript file.

And they're writing tests for a lot of these autogenerated methods. Because we do code reviews and they insist on testable code. I think this is unnecessary, but I've been seriously outvoted on this issue (having tests for one or two of the autogenerated methods, leaving the rest untested until you actually run into a problem is my preferred option). I would object, and I have. Oh well, my total lines of code written is through the roof, well on it's way to the moon, far exceeding people who've been writing code for more than double the amount of time I've been here. And it's useful code, and "useful" tests, so ...

> The approach I take is to generate actions with all the normal code in them as scaffold (for CRUD actions) - so for each one auth, then setup, then business logic,

Modifying autogenerated code is tricky and dangerous. You should never do it. It takes discipline, but you should always change the generators, never the code.


If it has been generated as boilerplate (e.g. To build out an API) with the explicit purpose of being extended, I think it's fine. It just saves a lot of typing. It's only inappropriate if you'd be better to adjust the template, not the code generated; if you're adding unique code (which you should be), it's fine IMO.


What is an alternate? I've never heard of that and Googling tells me nothing.


I'm guessing that means something more like "alternatives," but that's just a guess.


s/alternates/substitutes/g

yeah, basically type coercion/checking and interfaces have replaced generics in some (not all) use cases


Even with the delve debugger?


Despite being a great work, delve is slow and sometimes might skip some of my breakpoints and have problems in debugging goroutines.


Yeah, it can get pretty confusing. It would nice if there was a way to define a breakpoint that only gets tripped by a specific goroutine.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: