caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Name of currently executing function
@ 2008-07-14  5:27 Dave Benjamin
  2008-07-14 13:53 ` [Caml-list] " blue storm
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Benjamin @ 2008-07-14  5:27 UTC (permalink / raw)
  To: caml-list

Hello,

Is there any way to find out the name of the currently executing 
function from within an OCaml program? I guess, technically, I'm 
interested in the grandparent. Something that would allow this:

let log msg =
   Printf.eprintf "%s: %s\n%!"
     (get_caller_function_name ())
     msg

I'm guessing the above is not possible, but perhaps there's some way to 
accomplish this using some combination of camlp4, back traces, 
profiling, or debugging?

Thanks,
Dave


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Name of currently executing function
  2008-07-14  5:27 Name of currently executing function Dave Benjamin
@ 2008-07-14 13:53 ` blue storm
  2008-07-15  6:13   ` Dave Benjamin
  2008-07-20 16:17   ` Dave Benjamin
  0 siblings, 2 replies; 6+ messages in thread
From: blue storm @ 2008-07-14 13:53 UTC (permalink / raw)
  To: Dave Benjamin; +Cc: caml-list

Here is a little camlp4 code for an ad-hoc solution :
http://bluestorm.info/camlp4/Camlp4GenericProfiler.ml

It's based upon the Camlp4Filters/Camlp4Profiler.ml from the camlp4
distribution.
The GenericMake functor will traverse your code and apply the
parametrized function to the body of each function declaration. You
can use it with a functor providing a  (with_fun_name : string ->
Ast.expr -> Ast.expr), transforming the Ast to your liking, given the
function name.

I've written a small LoggingDecorator module that operates on the
__LOG__ identifier. Example code :
  let __LOG_FUNC__ func msg =  Printf.eprintf "in function %s: %s\n%!" func msg
  let test_function p = if not p then __LOG__ "p is false !"

It will replace the __LOG__ identifier with a __LOG_FUNC__ "p".

You can change that behavior, in particular you could be interested
(for logging purpose) in the location of the function declaration, not
only his name : see how the initial Camlp4Profiler behavior (wich i
kept in the ProfilingDecorator) do that (Loc.dump).


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Name of currently executing function
  2008-07-14 13:53 ` [Caml-list] " blue storm
@ 2008-07-15  6:13   ` Dave Benjamin
  2008-07-20 16:17   ` Dave Benjamin
  1 sibling, 0 replies; 6+ messages in thread
From: Dave Benjamin @ 2008-07-15  6:13 UTC (permalink / raw)
  To: blue storm; +Cc: caml-list

blue storm wrote:
> Here is a little camlp4 code for an ad-hoc solution :
> http://bluestorm.info/camlp4/Camlp4GenericProfiler.ml

This works very well. Thank you very much for the example.

On a related note, I was trying to understand how these new syntax 
filters work, and I am a bit confused by how I'm supposed to use 
Camlp4Tracer. I tried compiling a simple test program with:

camlp4 -parser ocaml -filter tracer -printer ocaml

It complained about an unknown value "Debug.mode", which I figured out 
was in the Camlp4 library, so I added that library and the line:

module Debug = Camlp4.Debug

to my program. Then it complained about an unbound value "exc". I looked 
at the Camlp4Tracer.ml to discover that it expects an exception named 
"exc" to be in scope with every function. I'm not sure what this is for, 
but I was able to get it to compile by creating a toplevel variable. My 
test program looks like the following now:

(*pp camlp4 -parser ocaml -filter tracer -printer ocaml *)

module Debug = Camlp4.Debug

let exc = Not_found

let test () =
   print_endline "this is output"

let () =
   test ()

And my Makefile looks like this:

OCAMLMAKEFILE := OCamlMakefile

SOURCES := main.ml
USE_CAMLP4 := yes
PACKS := camlp4.lib
RESULT := main

include $(OCAMLMAKEFILE)

Now, I can get tracing output:

% CAMLP4_DEBUG=* ./main
camlp4-debug: tracer: Not_found at File "main.ml", line 8, characters 16-32
this is output

So, is this the way it's supposed to work? Is this exception supposed to 
be some sort of marker for logging purposes? It seems like maybe the 
Printexc stuff was accidentally pasted in from the 
Camlp4ExceptionTracer, but without any docs, it's hard to tell for sure.

Dave


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Name of currently executing function
  2008-07-14 13:53 ` [Caml-list] " blue storm
  2008-07-15  6:13   ` Dave Benjamin
@ 2008-07-20 16:17   ` Dave Benjamin
  2008-07-20 17:35     ` blue storm
  1 sibling, 1 reply; 6+ messages in thread
From: Dave Benjamin @ 2008-07-20 16:17 UTC (permalink / raw)
  To: blue storm; +Cc: caml-list

Thanks again for your help, blue storm. I condensed this technique into 
a simple example for PLEAC, which I just committed here:

http://pleac.cvs.sourceforge.net/pleac/pleac/pleac/pleac_ocaml.data?r1=1.151&r2=1.152

It allows you to write this:

(* An example named function. *)
let test_function () =
   let str = "Hello, world!" in
   let num = 42 in
   LOG "str=\"%s\", num=%d" str num;
   print_endline "test complete"

(* Some code to run at the toplevel. *)
let () =
   LOG "not in a function";
   test_function ()

And get the following output:

<toplevel>[main.ml]: not in a function
test_function[main.ml]: str="Hello, world!", num=42
test complete

Regards,
Dave


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Name of currently executing function
  2008-07-20 16:17   ` Dave Benjamin
@ 2008-07-20 17:35     ` blue storm
  2008-07-20 23:41       ` Dave Benjamin
  0 siblings, 1 reply; 6+ messages in thread
From: blue storm @ 2008-07-20 17:35 UTC (permalink / raw)
  To: Dave Benjamin; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

Your combination of Profiler and Macros is really clever. I tried to do
something with macros before coming to the Profiler solution, but i didn't
work out.

This solution is elegant because it integrates well with the other
program-wide macros ( __LOCATION__ and __FILE__ ), and more powerful than
the ad-hoc __LOG__ handling.

The idea of directly modifying the decorate_this_expr declaration seemed a
little awkward at first, but it actually is as useful as the functor
solution (because all we can get anyway is the function name), while a lot
simpler. I think you could even suggest it for inclusion in the main Camlp4
distribution (it should be doable to rebuild the old Camlp4Profiler features
on top of that).

[-- Attachment #2: Type: text/html, Size: 761 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Name of currently executing function
  2008-07-20 17:35     ` blue storm
@ 2008-07-20 23:41       ` Dave Benjamin
  0 siblings, 0 replies; 6+ messages in thread
From: Dave Benjamin @ 2008-07-20 23:41 UTC (permalink / raw)
  To: blue storm; +Cc: caml-list

blue storm wrote:
> Your combination of Profiler and Macros is really clever. I tried to do 
> something with macros before coming to the Profiler solution, but i 
> didn't work out.

Thanks! The idea of using macros didn't occur to me until this morning. 
They certainly make it easier to work within the calling function's 
environment.

> This solution is elegant because it integrates well with the other 
> program-wide macros ( __LOCATION__ and __FILE__ ), and more powerful 
> than the ad-hoc __LOG__ handling.

Glad you think so.

> The idea of directly modifying the decorate_this_expr declaration seemed 
> a little awkward at first, but it actually is as useful as the functor 
> solution (because all we can get anyway is the function name), while a 
> lot simpler. I think you could even suggest it for inclusion in the main 
> Camlp4 distribution (it should be doable to rebuild the old 
> Camlp4Profiler features on top of that).

Well, I think you had the right idea in trying to generalize the 
profiler code so that it can be used for multiple purposes. I opted for 
the copy-and-modify approach mainly to keep the example small. My 
knowledge of camlp4 is pretty limited, and I have to admit I don't 
understand much of the profiler code. It's easier to suggest a slight 
modification than to write a new functor from scratch and then try to 
explain it.

Exposing __FILE__ isn't quite enough to reproduce the Camlp4Profiler's 
functionality, since we also need a way to trigger some code to execute 
at the start of every function. Either that, or we introduce a new 
keyword (say, "PROFILE"), that has to be explicitly mentioned at the top 
of each function to be profiled.

Dave


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-07-20 23:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-14  5:27 Name of currently executing function Dave Benjamin
2008-07-14 13:53 ` [Caml-list] " blue storm
2008-07-15  6:13   ` Dave Benjamin
2008-07-20 16:17   ` Dave Benjamin
2008-07-20 17:35     ` blue storm
2008-07-20 23:41       ` Dave Benjamin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).