* [Caml-list] Narrowing coercions for functions with optional parameters @ 2002-02-24 14:01 Tomasz Zielonka 2002-02-24 18:33 ` Stefano Zacchiroli 0 siblings, 1 reply; 5+ messages in thread From: Tomasz Zielonka @ 2002-02-24 14:01 UTC (permalink / raw) To: CAML list Hi I'm just curious - would it be possible to implement narrowing coercions for functions with optional parameters? It seems that such coercion is performed automatically in some situations. Example: # type basefun = int -> int ;; type basefun = int -> int # let f x = x ;; val f : 'a -> 'a = <fun> # (f :> basefun) ;; - : basefun = <fun> # let g ?(add = 0) x = x + add ;; val g : ?add:int -> int -> int = <fun> # (g :> basefun) ;; This expression cannot be coerced to type basefun = int -> int; it has type ?add:int -> int -> int but is here used with type int -> int (* Of course I can do: *) # (fun x -> g x : basefun) ;; - : basefun = <fun> (* Hmmm... now it gets strange... *) # let coerce f x = f x val coerce : ('a -> 'b) -> 'a -> 'b = <fun> # coerce g ;; - : int -> int = <fun> (* The above works, so g was used with type: int -> int *) (* But... *) # (g : int -> int) ;; This expression has type ?add:int -> int -> int but is here used with type int -> int (* ??? *) I hope someone can explain me this... best regards, tom -- .-. Tomasz Zielonka CYBER SERVICE oo| programista http://www.cs.net.pl /`'\ zielony@cs.net.pl (\_;/) tel: [48] (22) 723-06-79 | tel/fax: [48] (22) 723-01-75 ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Narrowing coercions for functions with optional parameters 2002-02-24 14:01 [Caml-list] Narrowing coercions for functions with optional parameters Tomasz Zielonka @ 2002-02-24 18:33 ` Stefano Zacchiroli 2002-02-24 19:50 ` Tomasz Zielonka 0 siblings, 1 reply; 5+ messages in thread From: Stefano Zacchiroli @ 2002-02-24 18:33 UTC (permalink / raw) To: CAML list On Sun, Feb 24, 2002 at 03:01:25PM +0100, Tomasz Zielonka wrote: > # let coerce f x = f x > val coerce : ('a -> 'b) -> 'a -> 'b = <fun> > > # coerce g ;; > - : int -> int = <fun> With such a call you haven't change the original "g" function so the coersion of "g" to "int -> int" doesn't work because it was applied to the old "g" function. Try this (after executing your examples of course): # let g = coerce g;; val g : int -> int = <fun> # (g : int -> int) ;; - : int -> int = <fun> Hope this helps. Cheers. -- Stefano Zacchiroli - undergraduate student of CS @ Univ. Bologna, Italy zack@cs.unibo.it | ICQ# 33538863 | http://www.cs.unibo.it/~zacchiro "I know you believe you understood what you think I said, but I am not sure you realize that what you heard is not what I meant!" -- G.Romney ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Narrowing coercions for functions with optional parameters 2002-02-24 18:33 ` Stefano Zacchiroli @ 2002-02-24 19:50 ` Tomasz Zielonka 2002-02-25 1:29 ` Jacques Garrigue 0 siblings, 1 reply; 5+ messages in thread From: Tomasz Zielonka @ 2002-02-24 19:50 UTC (permalink / raw) To: CAML list On Sun, Feb 24, 2002 at 07:33:23PM +0100, Stefano Zacchiroli wrote: > On Sun, Feb 24, 2002 at 03:01:25PM +0100, Tomasz Zielonka wrote: > > # let coerce f x = f x > > val coerce : ('a -> 'b) -> 'a -> 'b = <fun> > > > > # coerce g ;; > > - : int -> int = <fun> > > With such a call you haven't change the original "g" function so the > coersion of "g" to "int -> int" doesn't work because it was applied to > the old "g" function. Yes, I want it that way. Maybe I wasn't clear enough. Let's try again. My original question was: Is is possible to implement narrowing coercions for functions with optional parameters. Such coercion would erase optional parameters not found in target type. It is similar to coercing one class to another, when methods not found in the target class are hidden/"erased". Lets say you have several functions of the same type - some request handlers which take request as argument and return reply. type request and reply type handler = request -> reply You could place them in a list, hash table or some other structure, from which they are taken to handle typical requests. Imagine that in some situation you would like to call one handler from another passing some additional parameters. Of course the former handler will have different type (optional labeled parameters). Now you can't put it in the list with others (unless you wrap it in other function with appropriate type). Then it would be nice if you could just do (g :> handler), and get the optional parameters erased. When I was preparing an example, it came to me that such coercions are sometimes performed automatically: We have: val coerce : ('a -> 'b) -> 'a -> 'b = <fun> val g : ?add:int -> int -> int = <fun> When 'coerce' is applied to 'g' the type of 'g' must be unified with type of 'coerce's argument, that is: ?add:int -> int -> int is unified with 'a -> 'b The only way to do it is to _erase_ optional argument ?add and then substitute int for both 'a and 'b. So here 'g' was used with type int -> int, optional argument ?add being automatically erased. Here the coercion was implicit. It DOES WORK in Ocaml 3.04 I would like that it was also possible to explicitly coerce 'g' to type int -> int like in: (g : int -> int) or rather (g :> int -> int) But this DOESN'T WORK. So now the question is: Why implicit coercions are performed and explicit coercions are not allowed? > Try this (after executing your examples of course): > > # let g = coerce g;; > val g : int -> int = <fun> > # (g : int -> int) ;; > - : int -> int = <fun> Then the second phrase is only type assertion (or something) not coercion. Not an interesting coercion. > Hope this helps. > Cheers. Hope I was clear enough this time. tom -- .-. Tomasz Zielonka CYBER SERVICE oo| programista http://www.cs.net.pl /`'\ zielony@cs.net.pl (\_;/) tel: [48] (22) 723-06-79 | tel/fax: [48] (22) 723-01-75 ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Narrowing coercions for functions with optional parameters 2002-02-24 19:50 ` Tomasz Zielonka @ 2002-02-25 1:29 ` Jacques Garrigue 2002-02-25 9:44 ` Tomasz Zielonka 0 siblings, 1 reply; 5+ messages in thread From: Jacques Garrigue @ 2002-02-25 1:29 UTC (permalink / raw) To: zielony; +Cc: caml-list From: Tomasz Zielonka <zielony@cs.net.pl> > My original question was: Is is possible to implement narrowing coercions > for functions with optional parameters. > > Such coercion would erase optional parameters not found in target type. > It is similar to coercing one class to another, when methods not found > in the target class are hidden/"erased". There is a common misunderstanding on the meaning of (e :> t). It indeed allows some kind of coercion, but it does it by building a generic subtype of t, which is then unified to the type of e. This works for records and variants, where you just have to add a row variable to your type to produce such a generic subtype (yet, it doesn't really subsume all subtypes, only some of them). This is impossible with function types: there's no such generic description of a function with an array of optional parameters. The alternative is the real coercion notation (e : t1 :> t2). It says that e has type t1, and you want to coerce it to t2. Then you just have to compare t1 and t2, to make sure that t1 is a subtype of t2. It would be possible to coerce functions through the second notation, but then you bump into the next problem: such coercions would change the internal representation of the function. This is not the case of any coercion currently, and this would have strange effects on the subtyping relation: you can only subtype parts of the type you can modify. Not really clean. > When I was preparing an example, it came to me that such coercions are > sometimes performed automatically: > > We have: > val coerce : ('a -> 'b) -> 'a -> 'b = <fun> > val g : ?add:int -> int -> int = <fun> > > When 'coerce' is applied to 'g' the type of 'g' must be unified with > type of 'coerce's argument, that is: > > ?add:int -> int -> int > > is unified with > > 'a -> 'b > > The only way to do it is to _erase_ optional argument ?add and then > substitute int for both 'a and 'b. > > So here 'g' was used with type int -> int, optional argument ?add being > automatically erased. > Here the coercion was implicit. Indeed, you can see it as similar to the implicit coercion to change parameter order when you apply a labelled function in an order different from the original one. Here the coercion is only local: concrete functions are coerced, but for instance you cannot coerce a list of functions. Moreover it is not triggered by unification, but by simply examining known types during typing of application, when the expected function takes only unlabelled arguments. > So now the question is: > Why implicit coercions are performed and explicit coercions are not > allowed? So the answer is: because implicit "coercions" work ok on some specific syntactical cases, but cannot easily be generalized to full coercions. So, you are stuck with (fun x -> g x), which is in fact shorter than (g : ?add:int -> int -> int :> int -> int). By the way this is exactly what [coerce g] does, so you don't loose any efficiency by writing it explicitly. In fact you may even win some, because coercions have to be more careful about preserving the semantics, which can mean some extra cost. Cheers, Jacques Garrigue ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Narrowing coercions for functions with optional parameters 2002-02-25 1:29 ` Jacques Garrigue @ 2002-02-25 9:44 ` Tomasz Zielonka 0 siblings, 0 replies; 5+ messages in thread From: Tomasz Zielonka @ 2002-02-25 9:44 UTC (permalink / raw) To: Jacques Garrigue; +Cc: caml-list On Mon, Feb 25, 2002 at 10:29:30AM +0900, Jacques Garrigue wrote: > From: Tomasz Zielonka <zielony@cs.net.pl> > > There is a common misunderstanding on the meaning of (e :> t). It > indeed allows some kind of coercion, but it does it by building a > generic subtype of t, which is then unified to the type of e. > [...] Thanks for explanation. > So the answer is: because implicit "coercions" work ok on some > specific syntactical cases, but cannot easily be generalized to full > coercions. > > So, you are stuck with (fun x -> g x), which is in fact shorter than > (g : ?add:int -> int -> int :> int -> int). No problem. PS. Labels in OCaml are great :) tom -- .-. Tomasz Zielonka CYBER SERVICE oo| programista http://www.cs.net.pl /`'\ zielony@cs.net.pl (\_;/) tel: [48] (22) 723-06-79 | tel/fax: [48] (22) 723-01-75 ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-02-25 9:44 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-02-24 14:01 [Caml-list] Narrowing coercions for functions with optional parameters Tomasz Zielonka 2002-02-24 18:33 ` Stefano Zacchiroli 2002-02-24 19:50 ` Tomasz Zielonka 2002-02-25 1:29 ` Jacques Garrigue 2002-02-25 9:44 ` Tomasz Zielonka
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox