When you are debugging, it's very useful to do this:
var = calc()
print("var:", var)
Is there any language where this is easy to do? In C and C++ you can use the stringify macro operator # and in Ruby I found this question:
Ruby - print the variable name and then its value
The solution that uses a symbol :var and a block is what I want.
In D, I used this:
void trace(alias msg)() {
writeln(msg.stringof ~ ":" ~ to!string(msg));
}
But I'm not sure it's the best way, because it works only in simple cases. I have tried several ways, but sometimes you can get the string, but not the value (because variables are out of scope), or you have to mixin the template first and then call the function.
And what about other languages? Python? F#? Boo? Shell script (whichever shell)? Perl? (I prefer to stay away from Perl, tho). Tcl? Lisp, Scheme? Java? (it's highly unlikely that Java can do this).
Even in the languages where I found some kind of solution, it only works for simple cases. What if I want to print an arbitrary expression?
If I were designing a language, this feature would be a must-have. :-)
Here's a very general, but slightly ugly way to do it in D, using compile time function evaluation (CTFE) to generate the code as a string literal, and a mixin
statement to evaluate it:
import std.stdio, std.math;
// CTFE function that generates trace code.
string trace(string varName) {
return "writeln(\"" ~ varName ~ ": \", " ~ varName ~ ");";
}
void main() {
// Trace a function call.
mixin(trace("sqrt(5)"));
// Trace a variable.
int foo = 5;
mixin(trace("foo"));
}
The only problems are that manually typing mixin
everywhere is verbose and whatever you want to trace needs to be inside an ugly string literal.
Note that there are two kinds of mixins in D. Template mixins are better behaved in many ways, but string mixins (used in this example) are about as general as it gets, in that any code can in principle be generated via CTFE and then mixed in.
Trivial in any Lisp. In Racket (née PLT Scheme):
(define-syntax-rule (debug-info expr)
(format "~a is ~a" (quote expr) expr))
(let ((long-boring-name 5))
(display (debug-info long-boring-name)))
# displays "long-boring-name is 5"
(let ((fifty-two 52))
(display (debug-info (+ fifty-two 6))))
# displays "(+ fifty-two 6) is 58"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With