From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 67F75BC57 for ; Tue, 19 Oct 2010 22:51:01 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvUAAFehvUxV6aAZm2dsb2JhbACDH51kUBUBAQEBAQgJCgkRIrJAkjGBIoM0dASKS4ME X-IronPort-AV: E=Sophos;i="4.57,352,1283724000"; d="scan'208";a="74069335" Received: from outgoing-smtp.namesco.net ([85.233.160.25]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 19 Oct 2010 22:50:58 +0200 Received: from [192.168.0.14] (helo=artemis2.hosts.co.uk) by outgoing-smtp.namesco.net with esmtp (Exim 4.67) (envelope-from ) id 1P8J94-00078U-Cm for caml-list@yquem.inria.fr; Tue, 19 Oct 2010 21:50:55 +0100 Received: from root by artemis2.hosts.co.uk with local (Exim 4.69) (envelope-from ) id 1P8J96-0003RO-40 for caml-list@yquem.inria.fr; Tue, 19 Oct 2010 21:50:56 +0100 To: From: Reply-To: Subject: =?utf-8?q?Re=3a=20=5bCaml=2dlist=5d=20Code=2dexecution=20=28evaluation=29=20time?= MIME-Version: 1.0 X-Mailer: Namesco Webmail v3.0 Message-ID: <1287521455941@names.co.uk> Date: Tue, 19 Oct 2010 21:50:55 +0100 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-namescosender: 0 2002 X-namesco: 192.168.0.171 X-Spam-Score: -1.0 (-) X-Spam: no; 0.00; foo:01 foo:01 bandel:01 ocaml:01 expr:01 cmo:01 cmx:01 ocamlc:01 ocamlopt:01 unspecified:01 argv:01 iter:01 wrote:01 wrote:01 overlap:01 It's also worth noting a few other things about execution order: 1) function call arguments - All arguments in a function call are evaluated, even if not needed (in right-to-left order - as David says - but don't rely on this). 2) function bodies - These are executed when at least as many arguments are supplied as are explicitly supplied in the definition of the function. For example: let f x =3D (print_string "X"; fun y -> (print_string "Y"; x + y));; - this will not print anything as 'f' is defined let g =3D f 5;; - this will print "X" as 'g' is defined - "Y" will be printed each time 'g' is called with an argument. 3) blank assignments - These are still fully evaluated, even though the results are thrown away. For example: let _ =3D (print_string "X"; 5);; - this will still print "X" 4) 'match' branch choice - The first matching branch (i.e. as it appears in the file) is chosen (if the conditions overlap). 5) 'if' and 'match' unused branches - These (obviously) don't execute at all. So these do not behave like functions. 6) logical operator short circuits - '||' and '&&' short-circuit left-to-right (i.e. don't evaluate the second argument if the first (i.e. leftmost) argument is "true" (for '||') or "false (for '&&'). So these do not behave like functions. For example: let foo x y =3D x && y;; (print_string "X"; false) && (print_string "Y"; false);; - this will print just "X" foo (print_string "X"; false) (print_string "Y"; false);; - this will print "YX", because it's a function call and not a logical operation. Mark. on 19/10/10 8:54 PM, David Allsopp wrote: > Oliver Bandel wrote: >> Hello, >> >> I want to refresh my OCaml knowledge after I (again) paused for a while. >> >> I want to know, when certain parts of the code are executed, >> for example if I have more than one let _ =3D ... >> statement in my code (for example in different comp0ilaion units each one >> of them). > > Expressions (as in, things listed in > http://caml.inria.fr/pub/docs/manual-ocaml/expr.html) are evaluated in the > order in which they appear in a source file. If you have two files A.ml and > B.ml which contain top-level statements, the order in which they execute > will depend on the order in which you link the resulting .cmo or .cmx files > (which should be left-to-right as passed to ocamlc/ocamlopt - don't know > where that's specified). > > As far as I can see, in pretty much all contexts within an expression where > order of evaluation could matter including, but probably not limited to: > > * Record initialisation (e.g. let i =3D ref 0 in {a =3D (incr i; !i); b =3D (incr > i; !i)}) > * Function application (similarly) > * let foo =3D _ and bar =3D _ in _ > > are intentionally left as unspecified (in practice, application and record > initialisation are right-to-left and let x =3D _ and y =3D _ is left-to-right > but the point is that you are never supposed to rely on that). > >> I also found an old code snippet with the following parts: >> >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> let fnames =3D List.tl(Array.to_list Sys.argv) >> >> (* some more code *) >> >> let _ =3D >> List.iter print_days_old fnames >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> >> So, the value fnames contains the args from the command line and can be >> used in the first statement of the code. > > [let fnames =3D ..] is a complete expression so it's evaluated before the [let > _] further down. > > David