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 mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 992477EE51 for ; Thu, 11 Apr 2013 08:36:09 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of mmatalka@gmail.com) identity=pra; client-ip=209.85.217.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="mmatalka@gmail.com"; x-sender="mmatalka@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of mmatalka@gmail.com designates 209.85.217.170 as permitted sender) identity=mailfrom; client-ip=209.85.217.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="mmatalka@gmail.com"; x-sender="mmatalka@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-lb0-f170.google.com) identity=helo; client-ip=209.85.217.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="mmatalka@gmail.com"; x-sender="postmaster@mail-lb0-f170.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjACAHlZZlHRVdmqm2dsb2JhbABQgmVXrzSSF4EBFg4BAQEBAQYLCwkUKIIfAQEEAScZARsSCwEDAQsGBQ4KCQQhDwEEDQIRAQUBChgTEodvAQMJBgELoEeML4J7hHcKGScDClmIfgEFDIw3glMHg0EDlR2DBIpRgzo/hEo X-IPAS-Result: AjACAHlZZlHRVdmqm2dsb2JhbABQgmVXrzSSF4EBFg4BAQEBAQYLCwkUKIIfAQEEAScZARsSCwEDAQsGBQ4KCQQhDwEEDQIRAQUBChgTEodvAQMJBgELoEeML4J7hHcKGScDClmIfgEFDIw3glMHg0EDlR2DBIpRgzo/hEo X-IronPort-AV: E=Sophos;i="4.87,453,1363129200"; d="scan'208";a="12756436" Received: from mail-lb0-f170.google.com ([209.85.217.170]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 11 Apr 2013 08:36:09 +0200 Received: by mail-lb0-f170.google.com with SMTP id x11so1267681lbi.29 for ; Wed, 10 Apr 2013 23:36:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=vGzbNfCuMZdiyPrZWkJv8v6Kt4sPjmHZhny87WRi6FI=; b=fR7ljmqPF8vVGnTGfCHoKpn5rLr9HYZjhqUOzhMDROjfxvg21Hp8PwqE0RokY1EQG1 mNh5nmMn8sQnmLvyzb5JJfj7WmUvQPXAaqc06nhXj/Yu7Q04d8kQRVsHB9PCK++LPPiI mm6JiVwLSS2JwLV52aEjdeyacyBs7twg9RYqpJSvdswuc0HCWP4+6I37xQWzdXearkGj OSnRdmumc/GN8LoHowoCikdrhxhHeA0CYpu1JaJ+UFIhGZehVIlqVWih9aQ1Yh/jA/qK qP3tbqxaU1l3+wUqtN96yCui2A8g+tnrxKMvX9tyxXEC8KjZpde0ftoBGi5Ks/kv3jix Lt9w== X-Received: by 10.112.156.2 with SMTP id wa2mr2659587lbb.17.1365662168188; Wed, 10 Apr 2013 23:36:08 -0700 (PDT) Received: from localhost ([2a01:7e00::f03c:91ff:fedf:4d21]) by mx.google.com with ESMTPS id b2sm1209467lbv.4.2013.04.10.23.36.07 (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Wed, 10 Apr 2013 23:36:07 -0700 (PDT) From: Malcolm Matalka To: Yaron Minsky Cc: Chet Murthy , Caml List References: <4989654.hHte10Um7f@groupon> Date: Thu, 11 Apr 2013 02:36:06 -0400 In-Reply-To: (Yaron Minsky's message of "Wed, 10 Apr 2013 19:37:49 -0400") Message-ID: <87obdld161.fsf@li195-236.members.linode.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [Caml-list] try...finally , threads, stack-tracebacks .... in ocaml On top of this, I have also had a lot of success using the Result type (and associated Monad) instead of Exceptions in Ocaml. You have to have a certain level of discipline to enjoy doing it completely but I have never had a stack-trace issue doing it because you already know where you have to handle every failure case. /M Yaron Minsky writes: > Oh, and as for the thread part of your point, I would strongly > recommend using a monadic concurrency library like Async or Lwt rather > than coding with system threads in OCaml. It does kill your > stack-traces (stack-traces and monadic libraries don't work so well > together), but it's totally worth the trade-off. Certainly your > deadlock and race-condition problems get a hell of a lot better. > > y > > On Wed, Apr 10, 2013 at 7:35 PM, Yaron Minsky wrote: >> Chet, are you sure that one looses the stack trace in this case? My >> example using Core seems to preserve it. Here's the code: >> >> open Core.Std >> >> let a () = let _ = "a" in raise Not_found >> let b () = let _ = "b" in a () >> >> let c () = >> let _ = "c" in >> protect ~f:b >> ~finally:(fun () -> ()) >> >> let d () = let _ = "d" in c () >> let () = d () >> >> And here's the native code stack-trace: >> >> $ ./z.native >> Fatal error: exception Not_found >> Raised at file "z.ml", line 3, characters 32-41 >> Called from file "lib/exn.ml", line 63, characters 8-11 >> Re-raised at file "lib/exn.ml", line 66, characters 12-15 >> Called from file "z.ml", line 11, characters 26-30 >> >> Here's the code for protect, which is a little different than your >> finally, but not by a lot. Maybe the biggest difference is that we >> have a special exception (Finally) which we use when the finally >> clause throws an exception from an exception handler, so we can >> deliver both the exception tha triggered the [finally] and the >> exception thrown by the [finally]. >> >> This is from the Exn module in Core. >> >> let protectx ~f x ~(finally : _ -> unit) = >> let res = >> try f x >> with exn -> >> (try finally x with final_exn -> raise (Finally (exn, final_exn))); >> raise exn >> in >> finally x; >> res >> ;; >> >> let protect ~f ~finally = protectx ~f () ~finally >> >> >> On Wed, Apr 10, 2013 at 6:16 PM, Chet Murthy wrote: >>> >>> People have previously asked about try...finally support in Ocaml, and >>> it's been observed (correctly) that you can write a little combinator >>> to give you this support, e.g. >>> >>> let finally f arg finf = >>> let rv = try Inl(f arg) with e -> >>> Inr e >>> in (try finf arg rv with e -> ()); >>> match rv with >>> Inl v -> v >>> | Inr e -> raise e >>> >>> The problem is, you discard stack-traceback when you rethrow the >>> exception. One can program around this explicitly by capturing the >>> backtrace string and appending it to the rethrown exception, but it's >>> cumbersome and won't work for exceptions like Not_found that are >>> already defined without a mutable string slot. >>> >>> It sure would be nice of ocaml had try...finally that preserved the >>> traceback information properly .... though maybe it isn't possible. >>> Certainly in the case where the finally block doesn't raise any >>> exceptions itself (even those that are caught silently), it seems like >>> it ought to be possible. >>> >>> In an unrelated but similar sense, when programming with threads in >>> ocaml, it's easy (easy!) to deadlock your program. Now, I've been >>> writing Java programs for years, and so am aware of how careful one >>> must be, and I'm writing my code using a single mutex protecting the >>> critical section. But I forgot and didn't mutex-protect one method -- >>> what merely printed out the contents of a shared daa-structure, and >>> when that printout coincided with a thread actually mutating the >>> data-structure, I got a deadlock. Not hard to track down, and I >>> chided myself for being lax. >>> >>> But the thing is, in Java (blecch!) I would have been able to use the >>> "javacore" facility to get a full-thread stack-traceback, and could >>> have used that to get a good idea of where my deadlock was. >>> >>> I'm not saying that this is something ocaml should have, but I figured >>> I'd ask: are others (who use threads in ocaml) wishing for something >>> like this? >>> >>> --chet-- >>> >>> >>> >>> -- >>> Caml-list mailing list. Subscription management and archives: >>> https://sympa.inria.fr/sympa/arc/caml-list >>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >>> Bug reports: http://caml.inria.fr/bin/caml-bugs