addshore
03/18/2025, 10:11 AM#ifdef FOO_BAR
doStuff();
#endif
Is there a similar way to do this sort of thing with toit?
The primary usecase for me would be to entirely avoid building verbose log lines, which in their call might create long strings etc, when there is no expectaiton for that log line to every be used?
The only alternative right now I guess would be commenting and un commenting lines continually?floitsch
03/18/2025, 10:19 AMif SOME-GLOBAL-CONSTANT: then the compiler will remove the dead code if it can see that the constant is false.floitsch
03/18/2025, 10:21 AMmy-log [block]:
if SHOULD-LOG: print block.call
SHOULD-LOG ::= true
main:
my-log: "$(expensive) construction of some long string"floitsch
03/18/2025, 10:22 AMif, but the expensive contruction would not be done (if SHOULD-LOG is set to false).addshore
03/18/2025, 1:47 PMLEVEL-DEBUG ::= 4
LEVEL-TRACE ::= 5
LOG-LEVEL ::= LEVEL-DEBUG
do-log-debug [block]:
if LOG-LEVEL >= LEVEL-DEBUG: print block.call
do-log-trace [block]:
if LOG-LEVEL >= LEVEL-TRACE: print block.call
main:
do-log-debug: "$(expensive) construction of some long debug string"
do-log-trace: "$(expensive) construction of some long trace string"
Or would this not get optimized down during compilation?floitsch
03/18/2025, 1:47 PMfloitsch
03/18/2025, 1:47 PMfloitsch
03/18/2025, 1:51 PMᐅ toit tools snapshot bytecodes /tmp/out.snapshot do-log-
Bytecodes for methods[2]: (only printing elements matching: "do-log-")
259: do-log-debug /home/flo/tmp/cp.toit:5:1
0/ 263 [016] - load local 2
1/ 264 [055] - invoke block S1
3/ 266 [053] - invoke static print <sdk>/core/print.toit:13:1
6/ 269 [090] - return null S1 1
272: do-log-trace /home/flo/tmp/cp.toit:8:1
0/ 276 [090] - return null S0 1addshore
03/19/2025, 8:19 AMfloitsch
03/19/2025, 8:19 AMaddshore
03/19/2025, 11:12 AMimport lite-logging
log ::= lite-logging.new-default lite-logging.DEBUG-LEVEL
main:
log.debug: "Hello, world!"
and
import log
import .levels
new-default level/int -> Logger:
return Logger log.default level
class Logger:
logger /log.Logger
level /int
constructor .logger/log.Logger .level/int:
logger = logger
level = level
debug [block]:
if level >= DEBUG-LEVEL: print block.callfloitsch
03/19/2025, 11:19 AMfloitsch
03/19/2025, 11:20 AMaddshore
03/19/2025, 11:27 AMimport lite-logging
LITE-LOG-LEVEL ::= lite-logging.DEBUG-LEVEL
log ::= lite-logging.new-default
main:
log.debug: "Hello, world!"
first, but LITE-LOG-LEVEL is not accessible in the classaddshore
03/19/2025, 11:27 AMfloitsch
03/19/2025, 11:28 AMfloitsch
03/19/2025, 11:29 AMTrue or False even if it's inside a class, but you would still have the problem, that these types are shared among all users of the logger.floitsch
03/19/2025, 11:30 AMfloitsch
03/19/2025, 11:30 AMlog ::= lite-logging.DebugLogger.
But you don't need any constant-folding for that.addshore
03/19/2025, 11:34 AMfloitsch
03/19/2025, 11:35 AMaddshore
03/19/2025, 11:54 AMimport lite-logging
log ::= lite-logging.new lite-logging.DEBUG-LEVEL
main:
log.debug: "Hello, world!"
and
import log as toit-log
import .levels
new level/int --name/string?=null-> Logger:
return Logger level --name=name
class Logger:
logger /toit-log.Logger
logger-level /int
constructor .logger-level/int --name/string?=null:
logger = toit-log.Logger (max toit-log.DEBUG-LEVEL logger-level) toit-log.DefaultTarget --name=name
logger-level = logger-level
log level/int [block] --tags/Map?=null -> none:
if logger-level <= level: logger.log level block.call --tags=tags
trace [block] --tags/Map?=null -> none:
// Uses the debug level logger, as the toit logger has no trace level..
if logger-level <= TRACE-LEVEL: logger.log DEBUG-LEVEL "TRACE: $(block.call)" --tags=tags
debug [block] --tags/Map?=null -> none:
if logger-level <= DEBUG-LEVEL: logger.log DEBUG-LEVEL block.call --tags=tags
info [block] --tags/Map?=null -> none:
if logger-level <= INFO-LEVEL: logger.log INFO-LEVEL block.call --tags=tags
warn [block] --tags/Map?=null -> none:
if logger-level <= WARN-LEVEL: logger.log WARN-LEVEL block.call --tags=tags
error [block] --tags/Map?=null -> none:
if logger-level <= ERROR-LEVEL: logger.log ERROR-LEVEL block.call --tags=tags
Which means I can use blocks to avoid possibly expansive strings for debug logging, and leave the logging in place when the app is run in different logging modes.
It doesnt compile away the stuff that won't be used though. but solves my main pain, and doesnt look that bad at allfloitsch
03/19/2025, 11:55 AMif.floitsch
03/19/2025, 11:55 AMfloitsch
03/19/2025, 11:55 AMaddshore
03/19/2025, 11:56 AM