I suspect you may be interested in the Expr "meta" proposal. Start reading approximately here: https://github.com/JuliaLang/julia/pull/3796#issuecomment-21428185
On Friday, July 25, 2014 03:17:06 AM Magnus Lie Hetland wrote: > On Thursday, July 24, 2014 9:51:57 PM UTC+2, Tim Holy wrote: > > On Thursday, July 24, 2014 12:09:59 PM Magnus Lie Hetland wrote: > > > I saw a mention of a @debug macro somewhere on this list, > > > which I assume doesn't exist either? > > > > @debug is alive and well in Toivo's amazing Debug.jl package. But since > > debugging will change radically once Keno's work lands, I wouldn't worry > > building a common infrastructure for both @assert and @debug. > > Ah, right. Awesome stuff :-) But it's quite different from what I meant – I > was just thinking of a macro for marking code that would be nulled/removed > if we're not running in debug mode (or whatever you want to call it). So > that assertions would be just a special case. I guess this is sort of what > -DNDEBUG (or, for that matter, -DDEBUG) in C/C++, or the __debug__ constant > in Python <https://docs.python.org/3/library/constants.html>, is used for. > > (Slightly rambling email below…) > > The Python setup is basically that __debug__ is true if you start Python > without the -O switch. The assert statement > <https://docs.python.org/3/reference/simple_stmts.html#assert>, then, is > then wrapped in an if __debug__ statement. This seems to me to be a > conservative and sensible setup, which could be separate from Debug.jl, > though, of course, if we had something like __debug__, it would be possible > for Debug.jl to use that to switch things off. I guess the “magic names” of > Python aren't that appropriate; perhaps it could simply be Base.debug? > > There would really be no reason for the kind of @debug macro I was talking > about, as one could just use if statements (as in Python), without any > overhead … maybe? Maybe not? Seems OK for simple cases: > > *julia> **const debug = false* > > *false* > > > *julia> **f() = if debug 42 else 41 end* > > *f (generic function with 1 method)* > > > *julia> **code_llvm(f, ())* > > > define i64 @"julia_f;18972"() { > > top: > > ret i64 41, !dbg !772 > > } > > But if I add some more … > > *julia> **function f()* > > * if debug* > > * print("Debug!")* > > * end* > > * 41* > > *end* > > *f (generic function with 1 method)* > > > *julia> **code_llvm(f, ())* > > > define i64 @"julia_f;18980"() { > > top: > > %0 = alloca [4 x %jl_value_t*], align 8 > > %.sub = getelementptr inbounds [4 x %jl_value_t*]* %0, i64 0, i64 0 > > store %jl_value_t* inttoptr (i64 4 to %jl_value_t*), %jl_value_t** %.sub, > align 8 > > %1 = load %jl_value_t*** @jl_pgcstack, align 8, !dbg !796 > > %2 = getelementptr [4 x %jl_value_t*]* %0, i64 0, i64 1, !dbg !796 > > %.c = bitcast %jl_value_t** %1 to %jl_value_t*, !dbg !796 > > store %jl_value_t* %.c, %jl_value_t** %2, align 8, !dbg !796 > > store %jl_value_t** %.sub, %jl_value_t*** @jl_pgcstack, align 8, !dbg !796 > > %3 = getelementptr [4 x %jl_value_t*]* %0, i64 0, i64 2 > > store %jl_value_t* null, %jl_value_t** %3, align 8 > > %4 = getelementptr [4 x %jl_value_t*]* %0, i64 0, i64 3 > > store %jl_value_t* null, %jl_value_t** %4, align 8 > > %5 = load %jl_value_t** %2, align 8, !dbg !797 > > %6 = getelementptr inbounds %jl_value_t* %5, i64 0, i32 0, !dbg !797 > > store %jl_value_t** %6, %jl_value_t*** @jl_pgcstack, align 8, !dbg !797 > > ret i64 41, !dbg !797 > > } > > I can see that this might be left to LLVM, but the native code for the two > is still pretty different. So … it seems the if-statement does give some > overhead? In that case, we might need some macro anyway, for this kind of > functionality, perhaps. Maybe @ifdebug? > > I don't know. Initially, I guess having just a global constant indicating > whether we are in a more tentative mode of running the code (whether we > call it debug or something else) or if we're running things in a more > optimized setting, coupled with a code-expansion-level if-statement for > @assert (and a runtime if-statement for assert) would be an OK start. > > Judging by the precedence established by the current switches (such as > --check-bounds={yes|no}) perhaps making the functionality more specific > might even be desired, I guess, and limiting this to *only* assertions, > with --assertions={yes|no}, perhaps? Less stepping on Debug.jl's (or LLVM > dbg's) toes, maybe?
