Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: luc.maranget@inria.fr (Luc Maranget)
To: Sanghyeon Seo <sanxiyn@gmail.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Static exception in lambda code
Date: Fri, 11 Apr 2008 14:22:13 +0200	[thread overview]
Message-ID: <20080411122213.GA32623@yquem.inria.fr> (raw)
In-Reply-To: <5b0248170804110304q2a968b94uf0402cd3a54ad0df@mail.gmail.com>

> Luc Maranget suggested that static exception mechanism in lambda code,
> namely Lstaticcatch and Lstaticraise, could be used to implement break
> and continue.
> 
> However, this doesn't work right now. In bytecomp/simplif.ml,
> simplify_exits simplify
> (catch (seq (exit 1) (assign a b)) with (1) unit) to
> (seq unit (assign a b))
> which is not appropriate.

Interesting.

> 
> The comment says: "simplify catch body with (i ...) handler ... if
> (exit i ...) occurs exactly once in body, substitute it with handler".
> simplify_exits suppress catch if no exit occurs in body, which is
> nice, but this simplification is dangerous if one is to use this
> mechanism to implement break and continue.
> 
> So, which is the case?
> 1. The simplification is not safe, so it should be removed.
> 2. The simplification is consistent with intended semantics of static
> catch/raise, so static catch/raise is not directly useful to implement
> break/continue or for that matter, return.

Point 2, I guess. Simplifiation assumes a local-function semantics

(exit 1 e) is (apply f1 e)
(catch e1 (1 x) e2) is let f x = e1 in e1
[additionally, (exit i e) always occur in terminal position in e1]

This is the semantics assumed by the pattern-matching compiler, which
introduces all those exit/catch in the lambda-code.

However, later in the compiler (eg bytecode production)
(remaining) exit/catch pairs are compiled
as follows (informaly)

(exit i) ->
  branch labi

(catch e1 with (1 x) e2) ->
   [[ e1 ]]
   branch end 
 labi:
    [[ e2 ]]
 end: 
(actual code may be slightly different, with additional
stack adjustments)

Hence my idea to compile break with exit/catch


But, as you discovered, optimizing away break is wrong,
because you loose the branch/label effect.

There may be a simple solution :
add a flag to Lstaticatch, so as to inform simplif
wether the problematic optimization apply to it or not.

There is a similar trick in simplif for let's,
let's are tagged for simplif to know what kind of
optimisation are applicable to them.

Cf. <bytecomp/lambda.mli>


type let_kind = Strict | Alias | StrictOpt | Variable

(* Meaning of kinds for let x = e in e':
    Strict: e may have side-effets; always evaluate e first
      (If e is a simple expression, e.g. a variable or constant,
       we may still substitute e'[x/e].)
    Alias: e is pure, we can substitute e'[x/e] if x has 0 or 1 occurrences
      in e'
    StrictOpt: e does not have side-effects, but depend on the store;
      we can discard e if x does not appear in e'
    Variable: the variable x is assigned later in e' *)


catch's from the match compiler should probably be something
like Alias, which catch's from break/continue should
probably be something like StrictOpt.


Finally, there remains a (potential) pitfall in the
semantics assumed by the match compiler :
  (exit 1 e) is (apply f1 e)
  (catch e1 (1 x) e2) is let f x = e1 in e1
  [additionally, (exit i e) always occur in tail-call position in e1]

This is [...]

I assume that you think the following to be  valid code :

  for k=1 to n do
    f (if .. then break else ())
  done

Then break is not in tail call position. I have the feeling it does
not hurt, but such things require more investigation.

-- 
Luc


      reply	other threads:[~2008-04-11 12:22 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-11 10:04 Sanghyeon Seo
2008-04-11 12:22 ` Luc Maranget [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080411122213.GA32623@yquem.inria.fr \
    --to=luc.maranget@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=sanxiyn@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox