caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] How an exception could be an argument
@ 2012-02-17 18:16 Pierre-Alexandre Voye
  2012-02-17 18:33 ` Edgar Friendly
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pierre-Alexandre Voye @ 2012-02-17 18:16 UTC (permalink / raw)
  To: caml-list

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

Hello, I'm trying to implement a scala concept "partial application" in
which one can chains pattern matching function. If the first failed, the
second is tried.
It seems it is impossible to give an exception as argument to a function.



exception Nothing;;

let (<|||>) a b = try a
with

  | Nothing ->  (try b
with

                   | Nothing -> raise
Nothing);;

val ( <|||> ) : 'a -> 'a -> 'a = <fun>


(raise Nothing) <|||>
"jj";;

Exception: Nothing.


But if I try :
try (raise Nothing)
with

  | Nothing ->  (try
"jj"with

                   | Nothing -> raise
Nothing);;

- : string = "jj"

Is there a workaround ?


Regards,
P-A
-- 
---------------------
https://twitter.com/#!/ontologiae/
http://linuxfr.org/users/montaigne

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

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

* Re: [Caml-list] How an exception could be an argument
  2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
@ 2012-02-17 18:33 ` Edgar Friendly
  2012-02-17 18:49 ` Vincent Aravantinos
  2012-02-17 19:31 ` Tiphaine Turpin
  2 siblings, 0 replies; 4+ messages in thread
From: Edgar Friendly @ 2012-02-17 18:33 UTC (permalink / raw)
  To: Pierre-Alexandre Voye; +Cc: caml-list

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

Here is an example of giving an exception as an argument to a function:

let run_or ~cmd ~err = if Sys.command cmd <> 0 then raise err

and an example usage:

let config_fail = Failure ("Could not configure " ^ p.id)  in
run_or ~cmd:("sh configure" ^ config_opt) ~err:config_fail;

The problem with your code seems to be that you're passing in a result, so
the exception is being raised outside your try...with block.  OCaml's eager
evaluation means that you'll probably have to pass in a function and an
argument (or just a unit function), meaning that your <|||> will be much
uglier:

let (<|||>) (f,x) (g,y) = try f x with Nothing -> g y

((fun () -> raise Nothing), ()) <|||> ((fun str -> str), "ii")

E.

On Fri, Feb 17, 2012 at 1:16 PM, Pierre-Alexandre Voye <ontologiae@gmail.com
> wrote:

> Hello, I'm trying to implement a scala concept "partial application" in
> which one can chains pattern matching function. If the first failed, the
> second is tried.
> It seems it is impossible to give an exception as argument to a function.
>
>
>
> exception Nothing;;
>
> let (<|||>) a b = try a
> with
>
>   | Nothing ->  (try b
> with
>
>                    | Nothing -> raise
> Nothing);;
>
> val ( <|||> ) : 'a -> 'a -> 'a = <fun>
>
>

>
> (raise Nothing) <|||>
> "jj";;
>
> Exception: Nothing.
>
>
> But if I try :
> try (raise Nothing)
> with
>
>   | Nothing ->  (try
> "jj"with
>
>                    | Nothing -> raise
> Nothing);;
>
> - : string = "jj"
>
> Is there a workaround ?
>
>
> Regards,
> P-A
> --
> ---------------------
> https://twitter.com/#!/ontologiae/
> http://linuxfr.org/users/montaigne
>
>

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

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

* Re: [Caml-list] How an exception could be an argument
  2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
  2012-02-17 18:33 ` Edgar Friendly
@ 2012-02-17 18:49 ` Vincent Aravantinos
  2012-02-17 19:31 ` Tiphaine Turpin
  2 siblings, 0 replies; 4+ messages in thread
From: Vincent Aravantinos @ 2012-02-17 18:49 UTC (permalink / raw)
  To: caml-list

The arguments are evaluated before being passed to the function.
So in your first test, "Nothing" is raised before even entering "<|||>".
In the second case you're circumventing this by copying directly "raise 
Nothing" in the body of the function: this copy-pasting is not 
equivalent since you now force the evaluation of "raise Nothing" to 
happen within the scope of "try".

* The following could be a workaround:

# let (<|||>) (f1,arg1) (f2,arg2) = try f1 arg1 with Nothing -> try f2 
arg2 with Nothing -> raise Nothing;;
val ( <|||> ) : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>

# ((fun _ -> raise Nothing),()) <|||> ((fun _ -> "jj"),());;
- : string = "jj"

It looks a bit heavy on this example because we are working with constants.
But generally the constants come from some function application so it 
can fit in a not-so-ugly way in real code.

* If you don't care about the infix, the following induces less parentheses:

# let try_or_try f1 arg1 f2 arg2 = try f1 arg1 with Nothing -> try f2 
arg2 with Nothing -> raise Nothing;;
val try_or_try : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>

# try_or_try (fun _ -> raise Nothing) () (fun _ -> "jj") ();;
- : string = "jj"

* Note that you can simplify the second try since "try blah with Nothing 
-> raise Nothing" is actually equivalent to "blah"

This yields:

# let (<|||>) (f1,arg1) (f2,arg2) = try f1 arg1 with Nothing -> f2 arg2;;
val ( <|||> ) : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>


On 02/17/2012 01:16 PM, Pierre-Alexandre Voye wrote:
> (raise Nothing) <|||> "jj";;
> Exception: Nothing.
>
> But if I try :
> try (raise Nothing)  with
>   | Nothing ->  (try "jj"with
>                    | Nothing -> raise Nothing);;
> - : string = "jj"

-- 
Vincent Aravantinos
Postdoctoral Fellow, Concordia University, Hardware Verification Group
http://users.encs.concordia.ca/~vincent


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

* Re: [Caml-list] How an exception could be an argument
  2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
  2012-02-17 18:33 ` Edgar Friendly
  2012-02-17 18:49 ` Vincent Aravantinos
@ 2012-02-17 19:31 ` Tiphaine Turpin
  2 siblings, 0 replies; 4+ messages in thread
From: Tiphaine Turpin @ 2012-02-17 19:31 UTC (permalink / raw)
  To: caml-list

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

This behavior is expected given than OCaml is strict, and your operator
<|||> would be an ordinary function (unlike || and &&). You have to use
either functions (or lazy values) instead of expressions, or options
instead of exceptions.

Tiphaine


Le 17/02/2012 19:16, Pierre-Alexandre Voye a écrit :
> Hello, I'm trying to implement a scala concept "partial application"
> in which one can chains pattern matching function. If the first
> failed, the second is tried.
> It seems it is impossible to give an exception as argument to a function.
>
>
>
> exception Nothing;;
>
> let (<|||>) a b = try a
> with                                                                                                                                                                                                        
>
>   | Nothing ->  (try b
> with                                                                                                                                                                                                           
>
>                    | Nothing -> raise
> Nothing);;                                                                                                                                                                                      
>
> val ( <|||> ) : 'a -> 'a -> 'a = <fun> 
>
>
> (raise Nothing) <|||>
> "jj";;                                                                                                                                                                                                        
>
> Exception: Nothing. 
>
>
> But if I try :
> try (raise Nothing) 
> with                                                                                                                                                                                                           
>
>   | Nothing ->  (try
> "jj"with                                                                                                                                                                                                         
>
>                    | Nothing -> raise
> Nothing);;                                                                                                                                                                                      
>
> - : string = "jj" 
>
> Is there a workaround ?
>
>
> Regards,
> P-A
> -- 
> ---------------------
> https://twitter.com/#!/ontologiae/ <https://twitter.com/#%21/ontologiae/>
> http://linuxfr.org/users/montaigne
>


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

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

end of thread, other threads:[~2012-02-17 18:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
2012-02-17 18:33 ` Edgar Friendly
2012-02-17 18:49 ` Vincent Aravantinos
2012-02-17 19:31 ` Tiphaine Turpin

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).