Version française
Home     About     Download     Resources     Contact us    
Browse thread
camlp4 pa_macro
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Peter Jolly <peter@j...>
Subject: Re: [Caml-list] camlp4 pa_macro
Dmitry Bely wrote:
> Is it possible to achieve with pa_macro something like this:
> 
> IFDEF NDEBUG THEN
> DEFINE LOG(expr) = ()
> ELSE
> DEFINE LOG(expr) = Printf.printf expr
> ENDIF
> ...
> LOG("x=%d,y=%d" x y);
> 
> Unfortunately the code above does not work: debug version is OK, but then
> NDEBUG is turned on I have
> 
> "This expression is not a function, it cannot be applied" on LOG()
> expression.

Getting camlp4 to pretty-print the code after macro expansion is a
useful technique for debugging this sort of problem:

	$ camlp4 pa_o.cmo pa_op.cmo pr_o.cmo pa_macro.cmo test.ml
	...
	Printf.printf ("x=%d,y=%d" x y)

It should be clear why that isn't working.

> If I use
> 
> LOG "x=%d,y=%d" x y;
> 
> then the release version surprisingly works, but the debug one gives
> 
> "Parse error: currified constructor"

Yes, because this does not pass any arguments to the LOG macro - it
expands it with an empty <expr>.  So this works in the latter case,
because LOG just expands to "Printf.printf", but in the former case you
end up with

	() "x=%d,y=%d" x y

which is a syntax error as reported.

> How to overcome this?

	IFDEF NDEBUG THEN
	DEFINE LOG = Printf.kprintf ignore
	ELSE
	DEFINE LOG = Printf.printf
	ENDIF

Or just replace all instances of LOG with "if debug then Printf.printf",
on the grounds that the compiler is probably clever enough to prune
conditions that always evaluate to false, and you probably won't notice
any significant difference in speed even if it isn't.