Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Compile Time Code Weaving in Go (deferpanic.com)
44 points by deferpanic on July 13, 2015 | hide | past | favorite | 10 comments


I'm torn, because for debugging and testing, this kind of instrumentation makes me salivate, but then I think about the kinds of codebases and, worse, library packages that will be built to depend on it.


One of the (many) reasons I find Java much more appropriate for large "important" projects (Go is terrific for small ones), is that Go is the least hackable language in recent memory. When you start a big project, you know that at some point -- maybe even four or five years hence -- you will need a hack around language semantics to solve something without rewriting the whole thing. Python has monkeypatching, Ruby has meta-programming, C and C++ hack themselves, Rust has unsafe and C, and Java has bytecode instrumentation (load-time *or build-time) and Unsafe. With Go, you have absolutely nothing. You can't even drop down to C to get around semantics issues because you'll probably mess up the runtime. Every language has an escape hatch from factory-settings semantics. It's not wise to use it often, but sometime in the life of a big project, you will need it. Except Go. Go is utterly unhackable (at least not in any safe-ish way). The only "escape hatches" are source instrumentation and taking your chances with mucking about the runtime in C. But those are more taking a sledgehammer to the wall (and are available in any other language, too) than escape-hatches. It is very clear that Go is tailored to match Google's very specific process, like being very source-code- (rather than binary-library) -oriented.


I think if you are "ripping code in/out of your app everytime you need to do something" for debugging you need to create a logging system with multiple log levels. In log4j you can turn on TRACE logging for a particular subsystem to find out more about what is going on in that system. It would help a lot if the standard Go logging package would support multiple log levels.


>I think if you are "ripping code in/out of your app everytime you need to do something" for debugging you need to create a logging system with multiple log levels.

That's not a solution for the whole problem of making easy added/rippable changes to check specific behavior.

It leaves the code riddle with log calls and supporting code.


Adding log messages to code is a good thing. Every complex system needs a way to get visibility into it, and logs are a great way to do that.

I currently work on Hadoop, and pretty much every project in the Hadoop ecosystem has a huge number of log statements. Most of them are turned off at any given time for performance reasons, but when it's really necessary, we can turn them on.

I can see how having a source-code patching system would avoid the overhead of having an "if" statement to check if the log message was enabled. But what are you going to do when the library changes and your patch gets out of date? Having debuggability built-in to the library, rather than available as a 3rd-party add-on, is a feature, not a bug. Hadoop also supports changing the log level at runtime, and it seems like this source code patching system does not. So while this is a very clever system and may have some specific use-cases where it's useful, I think log levels are a better way to go in most cases.


> One of the things in Go that frustrates me is packaging and it’s not because I have 20 dependencies that I’m including in each project. I don’t have a problem with that cause we don’t do that at DeferPanic.

Sounds like they're implying that dependencies are bad? Coming from Node, that sounds like a painful and copypastey way to write code. Can someone explain this to me?


I'm guessing that they don't require much outside of the std lib for their application[1]. The Go std lib is pretty well featured.

The DeferPanic client depends on 12 packages, all from the std lib[2].

However, there's a high likelihood of their clients using 3rd party packages, so they would see it quite often.

[1]: which seems to provide Go application stats in a friendly and discover-able way. I personally haven't used it, but it looks fairly nice. https://deferpanic.com/about

[2]: https://godoc.org/github.com/deferpanic/deferclient/defercli...


This is an interesting external approach to metaprogramming in Go. After working with languages that have full metaprogramming capabilities, you really take for granted what metaprogramming gives you. The section "The Problem" really drives it home for me.


Looks promising. Can anyone experienced in Aspect-Oriented Programming say how complete/useful this implementation is?


I will only speak to the completeness as compared to other AOP[1] implementations[2]. Note that other[3] languages[4] address these concerns within the language definition themselves. Also, keep in mind that this project has just recently come into existence and should not yet be expected to support what mature AOP projects like AspectJ have been able to accomplish.

Considering the newness of the project, it seems to have good support for simple AOP use. There are a significant number of pointcuts missing when compared to AspectJ's pointcuts[5], though some are not applicable in Go.

The "after throwing" advice is inapplicable to Go[6], so can be discounted. However, "after returning" seems not to be supported yet and "around" is limited to call pointcuts.

All of this assumes that the project operates as advertised as I have no first-hand experience with this one.

1 - http://www.eclipse.org/aspectj/doc/released/progguide/index....

2 - http://www.postsharp.net/aop.net

3 - http://ruby-doc.com/docs/ProgrammingRuby/html/tut_modules.ht...

4 - http://www.artima.com/scalazine/articles/stackable_trait_pat...

5 - http://www.eclipse.org/aspectj/doc/released/progguide/semant...

6 - http://blog.golang.org/error-handling-and-go




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

Search: