var debugging debug = true // or flip to false
type debug bool
func (d debug) Printf(format string, args ...interface{}) {
if d {
log.Printf(format, args...)
}
}
and then your code can just write
debug.Printf("foo %d %.2f", 42, 12)
Dave.
thanks
Dan
--
Omnes mundum facimus.
Dan Kortschak <dan.ko...@adelaide.edu.au>
F9B3 3810 C4DD E214 347C B8DA D879 B7A7 EECC 5A40
Note that in all these cases, the arguments will be evaluated even if debug is false. This is different in effect and cost from the #define idiom of C.
The compiler is unlikely to be clever any time soon in this sort of thing.
-rob
package main
import "log"
const debug debugging = true // or flip to false
type debugging bool
func (d debugging) Printf(format string, args ...interface{}) {
if d {
log.Printf(format, args...)
}
}
func main() {
log.Printf("foo %d %.2f", 42, 12.7)
}
> David's example had a couple of bugs. Here's a version that works, and also promotes the debug flag to a const (it was a var in the original). Method on const: why not?
>
> Note that in all these cases, the arguments will be evaluated even if debug is false. This is different in effect and cost from the #define idiom of C.
>
> The compiler is unlikely to be clever any time soon in this sort of thing.
Actually, the language requires that the arguments be evaluated, so s/unlikely/certain never/ and s/any time soon//.
-rob
Not if it says
d.Print(expensiveFunctionCall())
You can't compile away the function call without violating the spec.
Russ
-1.
"-1" with no reason given is less than enlightening.
Engineering makes progress through evaluating merits and tradeoffs, not through obtaining majority votes. Majority votes get you the kind of progress that we have in politics, namely none.
Do you have an engineering reason for your "-1"? Go is too young a language to be in stasis yet.
It is a simple response to a suggestion, and to some degree it acts as
a bellwether for the community, but, fair enough.
> conditional compilation [is] often needed in the real world
I reject this premise, even in C. It's weaker still in the context of
Go, which has no significant differences between architectures that
demand conditional compilation. (Architectural differences accounting
for the vast majority of the preprocessor's valid use-cases.)
I agree that a preprocessor is a quick and (at first glance) simple
answer to solving concrete problems of engineering, but (IMO) that
kind of naïvety quickly and invariably brings one to the Macro Hell of
unmaintainable codebases. Any problem which can be solved with a
#define is better, more properly solved with another tool -- full
stop.
For me, Go is a great language largely because it is light, airy, and
productive. Introducing a preprocessor compromises that philosophy to
solve problems that we don't actually have, based on the precedent of
historical mistakes.
In short, -1.
An elegant, if eccentric, approach is already available. It involves
gofmt -r, and an example is available at
$GOROOT/src/pkg/container/vector/Makefile
You're now describing syntactic preprocessors, which (as a rule) speak
to a different problem domain than lexical preprocessors. According to
Wikipedia[1],
"Syntactic preprocessors are typically used to customize the syntax
of a language, extend a language by adding new primitives, or embed a
Domain-Specific Programming Language inside a general purpose
language."
[1] http://en.wikipedia.org/wiki/Preprocessor#Syntactic_preprocessors
These goals are orthogonal to goals of efficiency, which you
identified as your primary motivation in the email I replied to. If I
misread that, my apologies.
In any case, I would be -1 on either type of preprocessor in Go. I
simply see no need.
These goals are orthogonal to goals of efficiency, which you
identified as your primary motivation in the email I replied to. If I
misread that, my apologies.
As a professional software developer, I simply do not accept the
assertion that conditional compilation is necessary for "commercial
production and flexible deployment." There is no problem for which it
is the best, or even a good, solution.
Even granting that, it's not evident to me that a preprocessor is the
best, or even a good, way to achieve it. IMO, it's rightly the domain
of the build tool, not the language.
Also pretty much any form of conditional compilation is
asking for a debugging and testing nightmare.
Go has 'if', 'efficiency' should be accomplished by the compiler being
smart enough to identify dead code,
> But a well designed mechanism for conditional compilation needn't have these
> problems. The bulk of them disappear simply by making conditional
> compilation well structured and an integral part of the language,
> grammatically integrated with Go. It's not particularly hard to do, but it
> does require willingness to accept that Go is not yet cast in stone. The
> same applies to conditional evaluation of arguments.
Write your test code as
if (debug) {
fmt.Println("Debugging")
}
Have two files in your package as follows:
release.go:
package p
const debug = false
debug.go:
package p
const debug = true
Write your Makefile like this:
GOFILES=... $(RELEASE_OR_DEBUG)
ifeq ($(DEBUG),)
RELEASE_OR_DEBUG = release.go
else
RELEASE_OR_DEBUG = debug.go
endif
Or something along those lines.
Ian
traceFn, traceT := trace.M("github.com/jimrobinson/httpclient", trace.Trace);
...
if traceT {
trace.T(traceFn, "http request: %v", req)
}