From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id D240C7EE7D for ; Tue, 2 Jun 2015 10:37:31 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=pra; client-ip=188.165.44.50; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=mailfrom; client-ip=188.165.44.50; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@5.mo4.mail-out.ovh.net) identity=helo; client-ip=188.165.44.50; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="postmaster@5.mo4.mail-out.ovh.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0B+AQDeaW1VnDIspbxbyCqCUwKBNDwQAQEBAQEBAREBAQEBAQgLCQkhLoQjAQEEOEARCxgJFg8JAwIBAgFFEwgCiC0B2REBAQgCIIoggSOEUzqELQEEi1eST5c4hB2DNAEBAQ X-IPAS-Result: A0B+AQDeaW1VnDIspbxbyCqCUwKBNDwQAQEBAQEBAREBAQEBAQgLCQkhLoQjAQEEOEARCxgJFg8JAwIBAgFFEwgCiC0B2REBAQgCIIoggSOEUzqELQEEi1eST5c4hB2DNAEBAQ X-IronPort-AV: E=Sophos;i="5.13,538,1427752800"; d="scan'208";a="132995924" Received: from 5.mo4.mail-out.ovh.net ([188.165.44.50]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 02 Jun 2015 10:37:31 +0200 Received: from mail242.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo4.mail-out.ovh.net (Postfix) with SMTP id 6EF5CFF9A0B for ; Tue, 2 Jun 2015 10:37:30 +0200 (CEST) Received: from localhost (HELO queueout) (127.0.0.1) by localhost with SMTP; 2 Jun 2015 10:37:30 +0200 Received: from amontsouris-652-1-56-245.w92-163.abo.wanadoo.fr (HELO ?192.168.1.15?) (romain@bardou.fr@92.163.39.245) by ns0.ovh.net with SMTP; 2 Jun 2015 10:37:27 +0200 Message-ID: <556D6B45.4060604@inria.fr> Date: Tue, 02 Jun 2015 10:37:25 +0200 From: Romain Bardou User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 MIME-Version: 1.0 To: caml-list@inria.fr References: <556C4512.2050002@free.fr> <556C89F3.3000206@free.fr> <556D64EC.7060800@inria.fr> <122414E6-2549-4386-8106-2D18ECB8D787@math.nagoya-u.ac.jp> In-Reply-To: <122414E6-2549-4386-8106-2D18ECB8D787@math.nagoya-u.ac.jp> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Ovh-Tracer-Id: 7730147286705408544 X-Ovh-Remote: 92.163.39.245 (amontsouris-652-1-56-245.w92-163.abo.wanadoo.fr) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: 0 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekuddrgeeiucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekuddrgeeiucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-Validation-by: romain@bardou.fr Subject: Re: [Caml-list] getting the name of a function from its body On 02/06/2015 10:21, Jacques Garrigue wrote: > On 2015/06/02 17:10, Francois Berenger wrote: >> >> On 06/01/2015 11:57 PM, Fabrice Le Fessant wrote: >>> The main reason for the absence of __FUNCTION__ is probably that it >>> does not really make sense : you might have several functions with the >>> same name within the same module : >>> >>> let f x = x+1 >>> let f list = List.map f list >>> >>> It makes sense in C, because you can only define a symbol once in a >>> file, so the pair (__FILE__, __FUNCTION__) is uniq (and if the >>> function is not static, it is probably even uniq within the >>> executable). >>> >>> In OCaml, it is probably better to use the pair (__FILE__, __LINE__) >>> to tell the dev where to search for the problem. >> >> Then, the triplet (__FILE__, __LINE__, __FUNCTION__) is unique in OCaml. >> >> The problem I saw a long time ago while working with people who were not programmers (but still scientits) >> is that they have more chance to fix an error in one of their input >> file when given the function name than when not. >> >> And since I created and maintain a logging library in OCaml, I was (and I am still) interested into making log messages as useful as possible to end users. > > > You make a good point here. > The subtlety however is that it would require keeping track of the enclosing function name in the compiler, which is not done at all currently. > Also, this feature would require some kind of specification: I suppose by function you mean the enclosing toplevel let, but we also have the case of classes, where the occurence might be in the initialization part or inside a method, and of course cases where the definition has no name (toplevel expression of pattern-matching with several components). > Also should we do something special for submodules? functors? > Anything may be better than nothing, but this ends up being clearly more complex than __FILE__ and __LINE__, which come directly from the parser and are readily available in the syntax tree. > > Jacques > Another possibility is to be able to write __FUNCTIONS__, which would be a map/hashtbl/whatever from __LINE__ to function names, for the current file (or maybe module). Example: let log line s = Printf.printf "File %s, function %s, line %d: %s" __FILE__ (Int_map.find line __FUNCTIONS__) line s let test () = log __LINE__ "hello" Well this example does not quite work because __LINE__ is not actually the line number of function test, so we actually need to find the biggest function line number which is less than __LINE__. The user could also improve backtraces thanks to this. He would add "let functions = __FUNCTIONS__" in all his files, then he would parse the backtrace string to get file names and line numbers, and finally he would find the function name for each file name and line number. I have no idea whether it is a good idea or not. But I guess __FUNCTIONS__ can be generated from the typed tree of a module, making it easier to implement than __FUNCTION__? Basically, add __FUNCTIONS__ in the environment before typing, and generate its actual value after typing. Cheers, -- Romain Bardou