* [Caml-list] partial eval question @ 2003-10-27 1:41 Ben Kavanagh 2003-10-27 7:14 ` Damien ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Ben Kavanagh @ 2003-10-27 1:41 UTC (permalink / raw) To: caml-list Say I have a function such as pow defined as let pow n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, x1*x1, p1) else pow_iter(n1-1, x1, p1*x1) in pow_iter(n, x, 1);; and I say let pow2 = pow 2 Are there any ML implementations that would automatically perform partial evaluation to create pow2 instead of using closures, possibly unfolding the pow_iter call? Would Caml ever have this capability? Ben ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 1:41 [Caml-list] partial eval question Ben Kavanagh @ 2003-10-27 7:14 ` Damien 2003-10-27 15:39 ` William Chesters 2003-10-28 15:09 ` Dmitry Lomov 2003-10-27 15:16 ` Vincent Balat [prof Moggi team] 2004-02-04 2:51 ` Walid Taha 2 siblings, 2 replies; 21+ messages in thread From: Damien @ 2003-10-27 7:14 UTC (permalink / raw) Cc: caml-list On Mon, 27 Oct 2003 01:41:49 -0000 Ben Kavanagh wrote: > Say I have a function such as pow defined as > > let pow n x = > let rec pow_iter (n1, x1, p1) = > if (n1 = 0) then p1 > else if (n1 mod 2 = 0) > then pow_iter(n1/2, x1*x1, p1) > else pow_iter(n1-1, x1, p1*x1) > in pow_iter(n, x, 1);; > > and I say > > let pow2 = pow 2 > > Are there any ML implementations that would automatically perform > partial evaluation to create pow2 instead of using closures, possibly > unfolding the pow_iter call? Would Caml ever have this capability? Multi-Stage Programming is your friend... <http://www.cs.rice.edu/~taha/MSP/> There are two ML implementations : Ocaml : MetaOCaml <http://www.cs.rice.edu/~taha/MetaOCaml/> SML : MetaML <http://www.cse.ogi.edu/PacSoft/projects/metaml/> let rec pow n = .< .~(match n with | 1 -> .< fun x -> x >. | n -> .< fun x -> x * .~(pow (n-1)) x>. ) >. (pow 3) get reduced into .<fun x -> x*x*x>. Damien ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 7:14 ` Damien @ 2003-10-27 15:39 ` William Chesters 2003-10-27 18:50 ` Andrew Lenharth ` (2 more replies) 2003-10-28 15:09 ` Dmitry Lomov 1 sibling, 3 replies; 21+ messages in thread From: William Chesters @ 2003-10-27 15:39 UTC (permalink / raw) To: caml-list Damien writes: > Multi-Stage Programming is your friend... > <http://www.cs.rice.edu/~taha/MSP/> > > There are two ML implementations : > Ocaml : MetaOCaml <http://www.cs.rice.edu/~taha/MetaOCaml/> > SML : MetaML <http://www.cse.ogi.edu/PacSoft/projects/metaml/> > > > let rec pow n = .< > .~(match n with > | 1 -> .< fun x -> x >. > | n -> .< fun x -> x * .~(pow (n-1)) x>. > ) > >. > > (pow 3) get reduced into .<fun x -> x*x*x>. And that's an improvement over double pow(double x, int n) { double it = 1; while (--n >= 0) it *= x; return it; } double pow3(double x, int n) { return pow(x, 3); } in what way exactly? (If it doesn't work for you, try -funroll-all-loops.) For these kinds of purposes, Multi-Stage Programming is a very labour-intensive and error-prone way of doing what mainstream compilers will do for you already. Maybe it has useful applications in e.g. generation of numerical codes, where inlining, unrolling, "templatization" and partial evaluation are not enough because major structural transformations are required. But then, maybe sophisticated jobs like that are always going to be easiest done with special-purpose code generators? ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 15:39 ` William Chesters @ 2003-10-27 18:50 ` Andrew Lenharth 2003-10-27 19:12 ` William Chesters 2004-02-04 2:59 ` Walid Taha 2003-10-27 19:17 ` Yann Regis-Gianas 2004-02-04 2:56 ` Walid Taha 2 siblings, 2 replies; 21+ messages in thread From: Andrew Lenharth @ 2003-10-27 18:50 UTC (permalink / raw) To: William Chesters; +Cc: caml-list On Mon, Oct 27, 2003 at 03:39:21PM +0000, William Chesters wrote: > And that's an improvement over > > double pow(double x, int n) { > double it = 1; > while (--n >= 0) it *= x; > return it; > } > > double pow3(double x, int n) { > return pow(x, 3); > } > > in what way exactly? (If it doesn't work for you, try > -funroll-all-loops.) And that's an improvement over template <int N> inline double pow (double x) { return x * pow<N-1>(x); } template<> inline double pow<0> (double x) { return 1.0; } in what way exactly? (If it doesn't work for you, try -O2) :) The C example relies on a fairly smart compiler to do interprocedual analysis. The C++ example only requires the inline keywork be honored, and you don't need explicit pow3 pow2, you have pow<3> pow<2> pow<any constant>. Gives a bit more control over code generation. Andrew ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 18:50 ` Andrew Lenharth @ 2003-10-27 19:12 ` William Chesters 2003-10-27 20:08 ` Jacques Carette 2003-10-27 22:11 ` Andrew Lenharth 2004-02-04 2:59 ` Walid Taha 1 sibling, 2 replies; 21+ messages in thread From: William Chesters @ 2003-10-27 19:12 UTC (permalink / raw) To: caml-list Andrew Lenharth writes: > And that's an improvement over > > template <int N> > inline double pow (double x) { > return x * pow<N-1>(x); > } > template<> > inline double pow<0> (double x) { > return 1.0; > } > > in what way exactly? What I wrote, the "obvious thing", is -- easy to write, and hard to get wrong -- gives much less confusing error messages if you get it slightly wrong -- easy to read -- uses a smaller subset of the language, so is especially easier for non-C++ experts -- more general, in that it doesn't blow up and use silly amounts of space (and probably more time too, given cache churn) if N is not tiny -- more general also in that the same code does both the general-purpose (n known only at runtime) and the special-purpose job > The C example relies on a fairly smart compiler to > do interprocedual analysis. Depends what you mean by fairly smart. This is standard stuff: gcc is really not the best optimising compiler around. > The C++ example only requires the inline keywork be honored, and > you don't need explicit pow3 pow2, you have pow<3> pow<2> pow<any > constant>. > > Gives a bit more control over code generation. It does. I personally feel (actually have learned the hard way) that using C++ templates for multi-stage programming is mostly much more trouble than it is worth---especially when you realise what careful exploitation of C-level specalisation by inlining can do. If you really want more control over code generation (not forgetting that just writing out what you want by hand is often the simplest option in practice!) then I think C++ templates are a dead end---far better to make the object language the same as the target language, as in MetaOcaml and similar. ------------------- 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] 21+ messages in thread
* RE: [Caml-list] partial eval question 2003-10-27 19:12 ` William Chesters @ 2003-10-27 20:08 ` Jacques Carette 2004-02-04 3:03 ` Walid Taha 2003-10-27 22:11 ` Andrew Lenharth 1 sibling, 1 reply; 21+ messages in thread From: Jacques Carette @ 2003-10-27 20:08 UTC (permalink / raw) To: caml-list > If you really want more control over code generation (not forgetting > that just writing out what you want by hand is often the simplest > option in practice!) then I think C++ templates are a dead end---far > better to make the object language the same as the target language, > as in MetaOcaml and similar. If you know what you want, MetaOcaml is great. If you are prototyping/experimenting, then a typeless symbolic language (like Scheme or Maple) give you much greater flexibility. MetaOcaml's contortions to get something like: > pow := proc(x,n::nonnegint) if n=0 then 1 else times(x,pow(x,n-1)) end if end proc; pow := proc(x, n::nonnegint) if n = 0 then 1 else times(x, pow(x, n - 1)) end if end proc > unapply(pow(x,5), x); x -> times(x, times(x, times(x, times(x, times(x, 1))))) is really quite burdensome. Having the freedom of dealing with 'open' terms as first-class citizens is really very powerful, if somewhat dangerous. I have found Thiemann's PGG as the 'front end', coupled with Scheme-to-YourFavoriteLanguage translation to be quite effective PE strategy, at least when more basic 'symbolic computation' is not enough. Jacques ------------------- 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] 21+ messages in thread
* RE: [Caml-list] partial eval question 2003-10-27 20:08 ` Jacques Carette @ 2004-02-04 3:03 ` Walid Taha 0 siblings, 0 replies; 21+ messages in thread From: Walid Taha @ 2004-02-04 3:03 UTC (permalink / raw) To: Jacques Carette; +Cc: caml-list Hi Jacques, Please see my last email in responce to Ben's original email. MSP in MetaOCaml doesn't require any "contortions". Walid. On Mon, 27 Oct 2003, Jacques Carette wrote: |> If you really want more control over code generation (not forgetting |> that just writing out what you want by hand is often the simplest |> option in practice!) then I think C++ templates are a dead end---far |> better to make the object language the same as the target language, |> as in MetaOcaml and similar. | |If you know what you want, MetaOcaml is great. If you are |prototyping/experimenting, then a typeless symbolic language (like Scheme or |Maple) give you much greater flexibility. MetaOcaml's contortions to get |something like: | |> pow := proc(x,n::nonnegint) if n=0 then 1 else times(x,pow(x,n-1)) end if |end proc; |pow := proc(x, n::nonnegint) | if n = 0 then 1 else times(x, pow(x, n - 1)) end if |end proc | |> unapply(pow(x,5), x); | x -> times(x, times(x, times(x, times(x, times(x, 1))))) | |is really quite burdensome. Having the freedom of dealing with 'open' terms |as first-class citizens is really very powerful, if somewhat dangerous. | |I have found Thiemann's PGG as the 'front end', coupled with |Scheme-to-YourFavoriteLanguage translation to be quite effective PE |strategy, at least when more basic 'symbolic computation' is not enough. | |Jacques | |------------------- |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 | -- ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 19:12 ` William Chesters 2003-10-27 20:08 ` Jacques Carette @ 2003-10-27 22:11 ` Andrew Lenharth 1 sibling, 0 replies; 21+ messages in thread From: Andrew Lenharth @ 2003-10-27 22:11 UTC (permalink / raw) To: William Chesters; +Cc: caml-list On Mon, Oct 27, 2003 at 07:12:59PM +0000, William Chesters wrote: > What I wrote, the "obvious thing", is > -- easy to write, and hard to get wrong Easy to write, maybe, if recursion is hard. Harder for compilers to optimize. Tests latter. > -- gives much less confusing error messages if you get it slightly > wrong > -- easy to read Which is less important in high performance situlations. > -- uses a smaller subset of the language, so is especially easier > for non-C++ experts > -- more general, in that it doesn't blow up and use silly amounts > of space (and probably more time too, given cache churn) if N is not > tiny When I dump the code, I see 2 * N bytes of code in the unrolled loop. When I dump your code, I see no loop unrolling, hence no point in even trying to specialize the case. Anytime you are doing code generation, you must be careful to avoid blow up. Such is life. As you alluded to in the cache churn comment idea unrolling requires mesurement. However, with the template code we are explicitly using code generation, in the c code, we are simply hoping the compiler will do something we want. > -- more general also in that the same code does both the > general-purpose (n known only at runtime) and the special-purpose > job yes, and properly written the template code will support that. > > The C example relies on a fairly smart compiler to > > do interprocedual analysis. > > Depends what you mean by fairly smart. This is standard stuff: gcc is > really not the best optimising compiler around. This is true. Therefore I tried this on both gcc and icc (intel's compiler). icc did worse on the c than gcc did (interesting). Especially since icc was trying to do interprocedual analysis. The C++ versions were very similar at the assembly level in both compilers. The body of the loop was just series of fmul is both compiler outputs. quick measurement with gettimeofday: compiler N=3 N=30 gcc 5181 89866 icc,c 18437 106522 icc,c++ 1336 1296 g++ 1297 1297 for 1M iterations of assignment of pow into a volatile double These are very dependent on compiler flags in the c case. Having icc be more aggressive with loop unrolling made matters worse, since the code no longer fit in L1. There was much less needing to tune compiler options with the template approach, it consistently gave the best code. I would venture to say that for performance, there is still need for a programmer visible code generation engine. > > The C++ example only requires the inline keywork be honored, and > > you don't need explicit pow3 pow2, you have pow<3> pow<2> pow<any > > constant>. > > > > Gives a bit more control over code generation. > > It does. I personally feel (actually have learned the hard way) that > using C++ templates for multi-stage programming is mostly much more > trouble than it is worth---especially when you realise what careful > exploitation of C-level specalisation by inlining can do. Relying on the compiler is risky business. Doing code generation and hoping the compiler will optimize something a certain way are really different things. Further, for really interesting code generation, C-level specalisation by inlining is utterly inadiquit. Some tasks, such as data marshalling engines, can benifit greatly from straight forward template style code generation (both in shorter development time and smaller code base), whereas there is no equivilent framework to do that in C. > If you really want more control over code generation (not forgetting > that just writing out what you want by hand is often the simplest > option in practice!) then I think C++ templates are a dead end---far > better to make the object language the same as the target language, > as in MetaOcaml and similar. Indeed, a unified approach is easier to use, though for performance the code generation needs to be tuned at runtime, a task C++ templates certainly cannot pretent to approach. Andrew Lenharth ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 18:50 ` Andrew Lenharth 2003-10-27 19:12 ` William Chesters @ 2004-02-04 2:59 ` Walid Taha 2004-02-04 5:53 ` Andrew Lenharth 1 sibling, 1 reply; 21+ messages in thread From: Walid Taha @ 2004-02-04 2:59 UTC (permalink / raw) To: Andrew Lenharth; +Cc: William Chesters, caml-list On Mon, 27 Oct 2003, Andrew Lenharth wrote: |On Mon, Oct 27, 2003 at 03:39:21PM +0000, William Chesters wrote: |> And that's an improvement over |> |> double pow(double x, int n) { |> double it = 1; |> while (--n >= 0) it *= x; |> return it; |> } |> |> double pow3(double x, int n) { |> return pow(x, 3); |> } |> |> in what way exactly? (If it doesn't work for you, try |> -funroll-all-loops.) | |And that's an improvement over | |template <int N> |inline double pow (double x) { | return x * pow<N-1>(x); |} |template<> |inline double pow<0> (double x) { | return 1.0; |} | |in what way exactly? (If it doesn't work for you, try |-O2) :) OK. There is an article specifically about this point: http://www.cs.rice.edu/~taha/publications/preprints/2003-12-01.pdf (Comments are welcome, actually, the paper is undergoing the final revision). |The C example relies on a fairly smart compiler to |do interprocedual analysis. The C++ example |only requires the inline keywork be honored, and you |don't need explicit pow3 pow2, you have pow<3> pow<2> |pow<any constant>. | |Gives a bit more control over code generation. The draw back with C++ templates, in this case, is that you have to wait until the C++ code is generate before you know it type checks. A key goal of MSP is to ensure that generated code is *always* well-typed. That actually has been achieved in the context of a wide-range of type systems. Walid. |Andrew | |------------------- |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 | -- ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2004-02-04 2:59 ` Walid Taha @ 2004-02-04 5:53 ` Andrew Lenharth 2004-02-05 21:29 ` Walid Taha 0 siblings, 1 reply; 21+ messages in thread From: Andrew Lenharth @ 2004-02-04 5:53 UTC (permalink / raw) To: Walid Taha; +Cc: caml-list On Tue, Feb 03, 2004 at 08:59:57PM -0600, Walid Taha wrote: > > On Mon, 27 Oct 2003, Andrew Lenharth wrote: (CUT C and C++ version) > |in what way exactly? (If it doesn't work for you, try > |-O2) :) Of course, after I posted this, I made a version that was much better. Sigh. > OK. There is an article specifically about this point: > > http://www.cs.rice.edu/~taha/publications/preprints/2003-12-01.pdf > > (Comments are welcome, actually, the paper is undergoing the final > revision). It is late, and I will more carefully read the paper tomorrow, but I do have a couple of initial questions. With C++ templates I can implement optimizations based on data type, as you mention in 4.1, and provide a default implementation to ensure a well-typed function. Can I get the same from MetaOCaml? Really I guess I am almost asking for ad-hoc polymorphism, but with a fall back polymorphic implementation. Examples (in C++) may include generating code for vector units (SSE, altivec, etc) for operations with known semantics (+, etc) if a type in a vector is basic and falling back to calling the operator on unknown types. Similar thing for choosing a bitwise copy of a container verses using the copy constructor of the members. For such type optimizations I want let t_eq x y = match (type x),(type y) with int,int -> int compare | float,float -> float compare | bool,bool -> (x && y)|| ((not x) && (not y)) | _,_ -> x = y This is a silly example in that it only uses the mechanism to avoid the runtime overhead for polymorphic functions, but it is late and I hope you can understand what I am getting at. Also, you say you can generate code at runtime, is the generated code garbage collected? > |The C example relies on a fairly smart compiler to > |do interprocedual analysis. The C++ example > |only requires the inline keywork be honored, and you > |don't need explicit pow3 pow2, you have pow<3> pow<2> > |pow<any constant>. > | > |Gives a bit more control over code generation. > > The draw back with C++ templates, in this case, is that you have to wait > until the C++ code is generate before you know it type checks. A key goal > of MSP is to ensure that generated code is *always* well-typed. That > actually has been achieved in the context of a wide-range of type systems. I was a bit confused by this paragraph at first, but the paper clarified it. I think you meant to imply that any code that could be generated by MSP will be well-typed. This is starting to sound like other type checking arguments :) It is correct for every way it is used v.s. it is correct for every way it could be used. Andrew -- "The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man." -- George Bernard Shaw No matter how cynical you become, it's never enough to keep up. -- Lily Tomlin Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it. -- A. Perlis ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2004-02-04 5:53 ` Andrew Lenharth @ 2004-02-05 21:29 ` Walid Taha 0 siblings, 0 replies; 21+ messages in thread From: Walid Taha @ 2004-02-05 21:29 UTC (permalink / raw) To: Andrew Lenharth; +Cc: caml-list Hello Andrew, On Wed, 4 Feb 2004, Andrew Lenharth wrote: |> OK. There is an article specifically about this point: |> |> http://www.cs.rice.edu/~taha/publications/preprints/2003-12-01.pdf |> |> (Comments are welcome, actually, the paper is undergoing the final |> revision). | |It is late, and I will more carefully read the paper tomorrow, but I |do have a couple of initial questions. | |With C++ templates I can implement optimizations based on data type, |as you mention in 4.1, and provide a default implementation to ensure |a well-typed function. Can I get the same from MetaOCaml? Really I |guess I am almost asking for ad-hoc polymorphism, but with a fall back |polymorphic implementation. No. Not in the current MetaOCaml, which is basically just OCaml + Brackets + Escape + Run As far as typing issues are concerned, there is an easy way to determine if something can be typed done in MetaOCaml or not: Erase your brackets, escapes, and run. If your program can't be typed in OCaml, it can't be typed in MetaOCaml. What you describe requires a change to the core type system, which MetaOCaml tries to keep unchanged. There are other research efforts that explore adding related changes to the core type system. If we have the resources, it would certainly be worthwhile to incorporating such changes into MetaOCaml. |Also, you say you can generate code at runtime, is the generated code |garbage collected? Not in the current (alpha) versions. Do I see a volunteer? :) |> |The C example relies on a fairly smart compiler to |> |do interprocedual analysis. The C++ example |> |only requires the inline keywork be honored, and you |> |don't need explicit pow3 pow2, you have pow<3> pow<2> |> |pow<any constant>. |> | |> |Gives a bit more control over code generation. |> |> The draw back with C++ templates, in this case, is that you have to wait |> until the C++ code is generate before you know it type checks. A key goal |> of MSP is to ensure that generated code is *always* well-typed. That |> actually has been achieved in the context of a wide-range of type systems. | |I was a bit confused by this paragraph at first, but the paper |clarified it. I think you meant to imply that any code that could be |generated by MSP will be well-typed. Yes. |This is starting to sound like other type checking arguments :) It is |correct for every way it is used v.s. it is correct for every way it |could be used. I am not sure I understand what you are saying. Can you clarify? Walid. ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 15:39 ` William Chesters 2003-10-27 18:50 ` Andrew Lenharth @ 2003-10-27 19:17 ` Yann Regis-Gianas 2003-10-28 10:46 ` William Chesters 2004-02-04 2:56 ` Walid Taha 2 siblings, 1 reply; 21+ messages in thread From: Yann Regis-Gianas @ 2003-10-27 19:17 UTC (permalink / raw) To: caml-list William Chesters wrote : > And that's an improvement over > > double pow(double x, int n) { > double it = 1; > while (--n >= 0) it *= x; > return it; > } > > double pow3(double x, int n) { > return pow(x, 3); > } > > in what way exactly? (If it doesn't work for you, try > -funroll-all-loops.) > > For these kinds of purposes, Multi-Stage Programming is a very > labour-intensive and error-prone way of doing what mainstream > compilers will do for you already. I agree with you that constant folding, inlining and unrolling are well known by common compilers. However, when you want to _control_ these optimisations, this is more difficult with standard optimizers since they are black-boxes. For example, the benefit of these optimizations is linked with the size of code, the processor type but also with the values of data (think of the sparse matrix example). All these parameters cannot be managed by a low level compiler optimizer. In MetaOCaml, the general process of multi-stage evaluation enables the user-control of optimization simply : let k = eval_processor_capabilities () let rec pow n = function | 1 -> .< fun x -> x >. | n when n < k -> .< fun x -> x * .~(pow (n-1)) x>. | n -> .< fun x -> x *. (.! (pow (n-1)) x >. > Maybe it has useful applications > in e.g. generation of numerical codes, where inlining, unrolling, > "templatization" and partial evaluation are not enough because major > structural transformations are required. But then, maybe > sophisticated jobs like that are always going to be easiest done with > special-purpose code generators? By adding the multi-stage evaluation into a programming language, we obtain one general, transparent and simple tool. Why should we develop or learn the usage of many special-purpose optimizers ? Yes, some work has to be done to enhance its user-friendliness but, in my opinion, this feature can be relevant in many daily programming situations (not only optimization). There are some papers about that, for example : "Accomplishments and Research Challenges in Meta-programming". Tim Sheard. -- Yann Regis-Gianas. ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 19:17 ` Yann Regis-Gianas @ 2003-10-28 10:46 ` William Chesters 2004-02-04 2:22 ` Walid Taha 0 siblings, 1 reply; 21+ messages in thread From: William Chesters @ 2003-10-28 10:46 UTC (permalink / raw) To: caml-list Yann Regis-Gianas writes: > I agree with you that constant folding, inlining and unrolling are well known > by common compilers. However, when you want to _control_ these > optimisations, this is more difficult with standard optimizers since they are > black-boxes. That's a strength as well as a weakness. In reasonably simple cases it "just works" and is less effort, more readable, more maintainable. > By adding the multi-stage evaluation into a programming language, we obtain > one general, transparent and simple tool. Why should we develop or learn the > usage of many special-purpose optimizers ? Partial/abstract evaluation is a pretty general purpose optimiser. Half seriously: Metaml improves on C++ templates by making the metalanguage the same as and more tightly integrated with the object language. Partial evaluation can almost be seen as going a step further and having the compiler infer the tightest meta/object boundary. Perhaps if there was a way of telling the partial evaluator "specialise this code block by value of parameter i / type of parameter j / whatever" (*) it would handle all the everyday tasks for which metaml is designed, and require considerably less effort and expertise. (*) to get this effect with good current compilers you have to isolate the block in a function, turn up the inlining sufficiently, and use "if" branches to trigger specialisation > By adding the multi-stage evaluation into a programming language, > we obtain one general, transparent and simple tool. It's not simple or transparent, and for many tasks it isn't necessary. Perhaps it's a good general tool for the generation of code for numerics etc.---it may help specialist library writers. For everyday programming I think one has to remember that heavyweight attempts to achieve generality are often not worth it. Simple things can be done by the compiler or just written out by hand. Complex things look nasty when hand-optimised, but if you try to do them "better and more generally" using metaprogramming, you are likely to take much longer, and end up with something which is hard to decipher and disappointingly doesn't generalise in quite the way you want. There is little point in trading the "complexity" of prolix, irritating but basically straightforward hand-specialised code for the genuinely challenging complexity of a meta-programming system. (It really does become extremely complicated when you start taking into account the detailed requirements of real world problems.) The most viable option is often to settle on a reasonably general and extensible conceptual framework (at the level of conventions rather than anything more formal) and implement just the bits of it that you actually need for your particular problem, encapsulated in a consistent way. ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-28 10:46 ` William Chesters @ 2004-02-04 2:22 ` Walid Taha 0 siblings, 0 replies; 21+ messages in thread From: Walid Taha @ 2004-02-04 2:22 UTC (permalink / raw) To: William Chesters; +Cc: caml-list Sorry for picking up this thread after such a long time, but I only now got a chance to see this email. On Tue, 28 Oct 2003, William Chesters wrote: | > By adding the multi-stage evaluation into a programming language, | > we obtain one general, transparent and simple tool. | |It's not simple or transparent, and for many tasks it isn't necessary. |Perhaps it's a good general tool for the generation of code for |numerics etc.---it may help specialist library writers. I'm note sure why you think MSP is "neither simple nor transparent". What can be simpler than having just three new constructs to do both generate and execute all programs, to be guaranteed statically that (many) generated programs will be well-typed even before you generate them, and to know that the three new constructs satisfy simple equational reasoning principles? "For many tasks, it isn't necessary" is an argument that can also be made against module systems, objects, functions, and pretty much anything that can be viewed as a language feature. The primary audience is indeed "specialist writers", who are interested in building program generators, and who build enough program generators to know what kind of support would actually help them in doing that. Note that it is NOT for *users* of program generators: it's for the people who *build* them. Peace. Walid. ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 15:39 ` William Chesters 2003-10-27 18:50 ` Andrew Lenharth 2003-10-27 19:17 ` Yann Regis-Gianas @ 2004-02-04 2:56 ` Walid Taha 2 siblings, 0 replies; 21+ messages in thread From: Walid Taha @ 2004-02-04 2:56 UTC (permalink / raw) To: William Chesters; +Cc: caml-list On Mon, 27 Oct 2003, William Chesters wrote: |Damien writes: | > Multi-Stage Programming is your friend... | > <http://www.cs.rice.edu/~taha/MSP/> | > | > let rec pow n = .< | > .~(match n with | > | 1 -> .< fun x -> x >. | > | n -> .< fun x -> x * .~(pow (n-1)) x>. | > ) | > >. | > | > (pow 3) get reduced into .<fun x -> x*x*x>. | |And that's an improvement over | | double pow(double x, int n) { | double it = 1; | while (--n >= 0) it *= x; | return it; | } | | double pow3(double x, int n) { | return pow(x, 3); | } | |in what way exactly? (If it doesn't work for you, try |-funroll-all-loops.) Two reasons: 1) MSP is finer grained (you usually DON'T want to unroll all loops), and 2) you can do it at runtime (it's not limited to compile-time specialization). Those two simple reasons have a huge impact when you are building bigger and more complex software systems. |For these kinds of purposes, Multi-Stage Programming is a very |labour-intensive and error-prone way of doing what mainstream |compilers will do for you already. Why is MSP labour intensive? More importantly, why do you think it is error-prone? |Maybe it has useful applications |in e.g. generation of numerical codes, where inlining, unrolling, |"templatization" and partial evaluation are not enough because major |structural transformations are required. But then, maybe |sophisticated jobs like that are always going to be easiest done with |special-purpose code generators? What kinds do you have in mind? MSP's primary target users are indeed builders of code generators, but you seem to suggest that that somehow needs to be limited to an elite group of "generator writers"... That's exactly what MSP is supposed to help Joe Programmer avoid. Walid. ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 7:14 ` Damien 2003-10-27 15:39 ` William Chesters @ 2003-10-28 15:09 ` Dmitry Lomov 1 sibling, 0 replies; 21+ messages in thread From: Dmitry Lomov @ 2003-10-28 15:09 UTC (permalink / raw) To: caml-list On Monday 27 October 2003 10:14, Damien wrote: > On Mon, 27 Oct 2003 01:41:49 -0000 Ben Kavanagh wrote: > > Say I have a function such as pow defined as > > > > let pow n x = > > [skip] > > > > let pow2 = pow 2 > > > > Are there any ML implementations that would automatically perform > > partial evaluation to create pow2 instead of using closures, possibly > > unfolding the pow_iter call? Would Caml ever have this capability? > > Multi-Stage Programming is your friend... > <http://www.cs.rice.edu/~taha/MSP/> > > There are two ML implementations : > Ocaml : MetaOCaml <http://www.cs.rice.edu/~taha/MetaOCaml/> > SML : MetaML <http://www.cse.ogi.edu/PacSoft/projects/metaml/> May I also humbly draw your attention to Dynamic Caml: http://oops.tercom.ru/dml :) Friendly, Dmitry -- Dmitry Lomov IntelliJ Labs / JetBrains Inc. http://www.intellij.com "Develop with pleasure!" ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 1:41 [Caml-list] partial eval question Ben Kavanagh 2003-10-27 7:14 ` Damien @ 2003-10-27 15:16 ` Vincent Balat [prof Moggi team] 2004-02-04 2:51 ` Walid Taha 2 siblings, 0 replies; 21+ messages in thread From: Vincent Balat [prof Moggi team] @ 2003-10-27 15:16 UTC (permalink / raw) To: Ben Kavanagh; +Cc: caml-list I am working on a "type-directed" partial evaluator for OCaml. I did an implementation a few years ago with Olivier Danvy (see http://www.pps.jussieu.fr/~balat/publications/balat-danvy.pdf) But it is still*experimental*: - only a small subset on ocaml - need a modified version of ocaml with a "call/cc" operator ex: # let rec power mul one x n = if n=0 then one else (mul x (power mul one x (n-1)));; (* We close by mul and one because the function to be normalized must be mostly polymorphic *) val power : ('a -> 'b -> 'b) -> 'b -> 'a -> int -> 'b = <fun> # let power3 mul one x = power mul one x 3;; val power3 : ('a -> 'b -> 'b) -> 'b -> 'a -> 'b = <fun> # normalize "power3";; - : unit = () (* Now the function power3 is normalized *) (* You can print the normalized code by: *) # normalize_nf "power3";; - : NormalForms.computation = (fun v7 v8 v9 -> let v10 = v7 v9 in let v11 = v10 v8 in let v12 = v7 v9 in let v13 = v12 v11 in let v14 = v7 v9 in let v15 = v14 v13 in v15) It is not available on the web any more (it was for ocaml 1.05) but I can send it to you if you are interested. I'm planning to update it and to try to extend it to a larger subset of ocaml. There are still a lot of opened questions to solve before having it included in ocaml... Otherwise, as pointed by Damien Pous, you can have a look at MetaOCaml, which is a multi-level language based on ocaml, that is a language that allows you to manipulate source code (program generation). Vincent Balat ---- Ben Kavanagh écrit : > > Say I have a function such as pow defined as > > let pow n x = > let rec pow_iter (n1, x1, p1) = > if (n1 = 0) then p1 > else if (n1 mod 2 = 0) > then pow_iter(n1/2, x1*x1, p1) > else pow_iter(n1-1, x1, p1*x1) > in pow_iter(n, x, 1);; > > and I say > > let pow2 = pow 2 > > Are there any ML implementations that would automatically perform > partial evaluation to create pow2 instead of using closures, possibly > unfolding the pow_iter call? Would Caml ever have this capability? > > Ben > > > ------------------- > 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 > ------------------- 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] 21+ messages in thread
* Re: [Caml-list] partial eval question 2003-10-27 1:41 [Caml-list] partial eval question Ben Kavanagh 2003-10-27 7:14 ` Damien 2003-10-27 15:16 ` Vincent Balat [prof Moggi team] @ 2004-02-04 2:51 ` Walid Taha 2004-02-04 10:26 ` Ben Kavanagh 2004-02-04 10:32 ` Ben Kavanagh 2 siblings, 2 replies; 21+ messages in thread From: Walid Taha @ 2004-02-04 2:51 UTC (permalink / raw) To: Ben Kavanagh; +Cc: caml-list Hi Ben, Below is a MetaOCaml (www.metaocaml.org) program that does what you were asking for. ----- begin ben.ml Trx.init_times (* Initialize MetaOCaml timer library *) (* Here's Ben's original code *) let pow n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, x1*x1, p1) else pow_iter(n1-1, x1, p1*x1) in pow_iter(n, x, 1);; let pow2 = pow 2 (* Here's a staged version of Ben's code *) let pow' n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, .<.~x1 * .~x1>., p1) else pow_iter(n1-1, x1, .<.~p1 * .~x1>.) in pow_iter(n, x, .<1>.);; let pow2 = pow' 2 (* Here's some code to get some timings *) let unstagedRunning = Trx.timenew "unstaged running"(fun () -> pow 5 3) let stage1Running = Trx.timenew "stage 1 running" (fun () -> .<fun x-> .~(pow' 5 .<x>.)>.) let compiling = Trx.timenew "compiling" (fun () -> .! stage1Running) let stage2Running = Trx.timenew "stage 2 running" (fun () -> (compiling 3)) let baseline = Trx.timenew "baseline" (fun () -> ()) (* Print all the timings *) let _ = Trx.print_times () (* Outpout of timer: __ unstaged running ______ 2097152x avg= 7.929525E-04 msec __ stage 1 running ________ 262144x avg= 7.248323E-03 msec __ compiling ________________ 8192x avg= 2.320860E-01 msec __ stage 2 running ______ 16777216x avg= 1.123075E-04 msec __ baseline _____________ 33554432x avg= 3.921819E-05 msec *) --- end ben.ml Walid. On Mon, 27 Oct 2003, Ben Kavanagh wrote: | |Say I have a function such as pow defined as | |let pow n x = | let rec pow_iter (n1, x1, p1) = | if (n1 = 0) then p1 | else if (n1 mod 2 = 0) | then pow_iter(n1/2, x1*x1, p1) | else pow_iter(n1-1, x1, p1*x1) | in pow_iter(n, x, 1);; | |and I say | |let pow2 = pow 2 | |Are there any ML implementations that would automatically perform |partial evaluation to create pow2 instead of using closures, possibly |unfolding the pow_iter call? Would Caml ever have this capability? | |Ben | | |------------------- |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 | -- ------------------- 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] 21+ messages in thread
* RE: [Caml-list] partial eval question 2004-02-04 2:51 ` Walid Taha @ 2004-02-04 10:26 ` Ben Kavanagh 2004-02-04 10:32 ` Ben Kavanagh 1 sibling, 0 replies; 21+ messages in thread From: Ben Kavanagh @ 2004-02-04 10:26 UTC (permalink / raw) To: 'Walid Taha'; +Cc: caml-list Walid, Thanks for your response. I was aware of MetaOCaml's ability to stage this computation and I have downloaded/run many of your benchmarks. My question was if anyone had an implementation where normal partial application (normal in ML's syntax) led to partial evaluation. It turns out that there was an implementation of this, namely Mark Leone/Peter Lee's Fabius compiler, which, unfortunately, has never been made available publicly. http://portal.acm.org/citation.cfm?id=231407&dl=ACM&coll=portal&CFID=111 11111&CFTOKEN=2222222 http://portal.acm.org/citation.cfm?id=289144&dl=ACM&coll=portal I concur that such an undiscriminating approach to partial evaluation in a program is not ideal, a point you touch on in a later mail to the Caml list. It does seem, though, that a useful syntax shortcut that made this direct partial-application -> partial-eval mapping available in the manner of Lee/Leone could be useful in MetaOCaml. Do you agree? Ben ------------------------------------------------------------------------ -------------- FIGHT BACK AGAINST SPAM! Download Spam Inspector, the Award Winning Anti-Spam Filter http://mail.giantcompany.com -----Original Message----- From: Walid Taha [mailto:taha@cs.rice.edu] Sent: Wednesday, February 04, 2004 2:51 AM To: Ben Kavanagh Cc: caml-list@inria.fr Subject: Re: [Caml-list] partial eval question Hi Ben, Below is a MetaOCaml (www.metaocaml.org) program that does what you were asking for. ----- begin ben.ml Trx.init_times (* Initialize MetaOCaml timer library *) (* Here's Ben's original code *) let pow n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, x1*x1, p1) else pow_iter(n1-1, x1, p1*x1) in pow_iter(n, x, 1);; let pow2 = pow 2 (* Here's a staged version of Ben's code *) let pow' n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, .<.~x1 * .~x1>., p1) else pow_iter(n1-1, x1, .<.~p1 * .~x1>.) in pow_iter(n, x, .<1>.);; let pow2 = pow' 2 (* Here's some code to get some timings *) let unstagedRunning = Trx.timenew "unstaged running"(fun () -> pow 5 3) let stage1Running = Trx.timenew "stage 1 running" (fun () -> .<fun x-> .~(pow' 5 .<x>.)>.) let compiling = Trx.timenew "compiling" (fun () -> .! stage1Running) let stage2Running = Trx.timenew "stage 2 running" (fun () -> (compiling 3)) let baseline = Trx.timenew "baseline" (fun () -> ()) (* Print all the timings *) let _ = Trx.print_times () (* Outpout of timer: __ unstaged running ______ 2097152x avg= 7.929525E-04 msec __ stage 1 running ________ 262144x avg= 7.248323E-03 msec __ compiling ________________ 8192x avg= 2.320860E-01 msec __ stage 2 running ______ 16777216x avg= 1.123075E-04 msec __ baseline _____________ 33554432x avg= 3.921819E-05 msec *) --- end ben.ml Walid. On Mon, 27 Oct 2003, Ben Kavanagh wrote: | |Say I have a function such as pow defined as | |let pow n x = | let rec pow_iter (n1, x1, p1) = | if (n1 = 0) then p1 | else if (n1 mod 2 = 0) | then pow_iter(n1/2, x1*x1, p1) | else pow_iter(n1-1, x1, p1*x1) | in pow_iter(n, x, 1);; | |and I say | |let pow2 = pow 2 | |Are there any ML implementations that would automatically perform |partial evaluation to create pow2 instead of using closures, possibly |unfolding the pow_iter call? Would Caml ever have this capability? | |Ben | | |------------------- |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 | -- ------------------- 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] 21+ messages in thread
* RE: [Caml-list] partial eval question 2004-02-04 2:51 ` Walid Taha 2004-02-04 10:26 ` Ben Kavanagh @ 2004-02-04 10:32 ` Ben Kavanagh 2004-02-05 21:11 ` Walid Taha 1 sibling, 1 reply; 21+ messages in thread From: Ben Kavanagh @ 2004-02-04 10:32 UTC (permalink / raw) To: 'Walid Taha'; +Cc: caml-list Walid, Thanks much for your response. I was aware of MetaOCaml's ability to stage this computation and I have downloaded/run many of your benchmarks. My question was more if anyone had an implementation where normal partial application (normal in ML's syntax) led to partial evaluation. It turns out that there was an implementation of this, namely Mark Leone/Peter Lee's Fabius compiler, which, unfortunately, has never been made available publicly. http://portal.acm.org/citation.cfm?id=231407&dl=ACM&coll=portal&CFID=111 11111&CFTOKEN=2222222 http://portal.acm.org/citation.cfm?id=289144&dl=ACM&coll=portal Such a coarse grained approach to code generation in a program is not necessarily ideal for all purposes, a point you touch on in a later mail to the Caml list in your statement about loop unrolling. It does seem, though, that a useful syntax shortcut that made this direct partial-application -> partial-evaluation mapping available in the manner of Lee/Leone could be useful in Caml, and maybe even more appropriately, MetaOCaml. Does this make sense? Ben ------------------------------------------------------------------------ -------------- FIGHT BACK AGAINST SPAM! Download Spam Inspector, the Award Winning Anti-Spam Filter http://mail.giantcompany.com -----Original Message----- From: Walid Taha [mailto:taha@cs.rice.edu] Sent: Wednesday, February 04, 2004 2:51 AM To: Ben Kavanagh Cc: caml-list@inria.fr Subject: Re: [Caml-list] partial eval question Hi Ben, Below is a MetaOCaml (www.metaocaml.org) program that does what you were asking for. ----- begin ben.ml Trx.init_times (* Initialize MetaOCaml timer library *) (* Here's Ben's original code *) let pow n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, x1*x1, p1) else pow_iter(n1-1, x1, p1*x1) in pow_iter(n, x, 1);; let pow2 = pow 2 (* Here's a staged version of Ben's code *) let pow' n x = let rec pow_iter (n1, x1, p1) = if (n1 = 0) then p1 else if (n1 mod 2 = 0) then pow_iter(n1/2, .<.~x1 * .~x1>., p1) else pow_iter(n1-1, x1, .<.~p1 * .~x1>.) in pow_iter(n, x, .<1>.);; let pow2 = pow' 2 (* Here's some code to get some timings *) let unstagedRunning = Trx.timenew "unstaged running"(fun () -> pow 5 3) let stage1Running = Trx.timenew "stage 1 running" (fun () -> .<fun x-> .~(pow' 5 .<x>.)>.) let compiling = Trx.timenew "compiling" (fun () -> .! stage1Running) let stage2Running = Trx.timenew "stage 2 running" (fun () -> (compiling 3)) let baseline = Trx.timenew "baseline" (fun () -> ()) (* Print all the timings *) let _ = Trx.print_times () (* Outpout of timer: __ unstaged running ______ 2097152x avg= 7.929525E-04 msec __ stage 1 running ________ 262144x avg= 7.248323E-03 msec __ compiling ________________ 8192x avg= 2.320860E-01 msec __ stage 2 running ______ 16777216x avg= 1.123075E-04 msec __ baseline _____________ 33554432x avg= 3.921819E-05 msec *) --- end ben.ml Walid. On Mon, 27 Oct 2003, Ben Kavanagh wrote: | |Say I have a function such as pow defined as | |let pow n x = | let rec pow_iter (n1, x1, p1) = | if (n1 = 0) then p1 | else if (n1 mod 2 = 0) | then pow_iter(n1/2, x1*x1, p1) | else pow_iter(n1-1, x1, p1*x1) | in pow_iter(n, x, 1);; | |and I say | |let pow2 = pow 2 | |Are there any ML implementations that would automatically perform |partial evaluation to create pow2 instead of using closures, possibly |unfolding the pow_iter call? Would Caml ever have this capability? | |Ben | | |------------------- |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 | -- ------------------- 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] 21+ messages in thread
* RE: [Caml-list] partial eval question 2004-02-04 10:32 ` Ben Kavanagh @ 2004-02-05 21:11 ` Walid Taha 0 siblings, 0 replies; 21+ messages in thread From: Walid Taha @ 2004-02-05 21:11 UTC (permalink / raw) To: Ben Kavanagh; +Cc: caml-list Hi Ben, It would certainly be useful to extend MetaOCaml with a partial evaluation construct. The key component that is needed is a nice implementation of a binding-time analysis (BTA). If someone (maybe you? :) is willing to implement such an analysis, it can be added into MetaOCaml as a library function: BTA : <a -> b -> c> -> a -> <b -> c> Best regards, Walid. On Wed, 4 Feb 2004, Ben Kavanagh wrote: |Walid, | |Thanks much for your response. I was aware of MetaOCaml's ability to |stage this computation and I have downloaded/run many of your |benchmarks. My question was more if anyone had an implementation where |normal partial application (normal in ML's syntax) led to partial |evaluation. It turns out that there was an implementation of this, |namely Mark Leone/Peter Lee's Fabius compiler, which, unfortunately, has |never been made available publicly. | |http://portal.acm.org/citation.cfm?id=231407&dl=ACM&coll=portal&CFID=111 |11111&CFTOKEN=2222222 |http://portal.acm.org/citation.cfm?id=289144&dl=ACM&coll=portal | |Such a coarse grained approach to code generation in a program is not |necessarily ideal for all purposes, a point you touch on in a later mail |to the Caml list in your statement about loop unrolling. It does seem, |though, that a useful syntax shortcut that made this direct |partial-application -> partial-evaluation mapping available in the |manner of Lee/Leone could be useful in Caml, and maybe even more |appropriately, MetaOCaml. | |Does this make sense? | |Ben | | | | |------------------------------------------------------------------------ |-------------- |FIGHT BACK AGAINST SPAM! |Download Spam Inspector, the Award Winning Anti-Spam Filter |http://mail.giantcompany.com | | |-----Original Message----- |From: Walid Taha [mailto:taha@cs.rice.edu] |Sent: Wednesday, February 04, 2004 2:51 AM |To: Ben Kavanagh |Cc: caml-list@inria.fr |Subject: Re: [Caml-list] partial eval question | | |Hi Ben, | |Below is a MetaOCaml (www.metaocaml.org) program that does what you were |asking for. | |----- begin ben.ml | |Trx.init_times (* Initialize MetaOCaml timer library *) | |(* Here's Ben's original code *) | |let pow n x = | | let rec pow_iter (n1, x1, p1) = | | if (n1 = 0) then | p1 | else if (n1 mod 2 = 0) then | pow_iter(n1/2, x1*x1, p1) | else pow_iter(n1-1, x1, p1*x1) | | in pow_iter(n, x, 1);; | | | |let pow2 = pow 2 | |(* Here's a staged version of Ben's code *) | |let pow' n x = | | let rec pow_iter (n1, x1, p1) = | | if (n1 = 0) then | p1 | else if (n1 mod 2 = 0) then | pow_iter(n1/2, .<.~x1 * .~x1>., p1) | | else pow_iter(n1-1, x1, .<.~p1 * .~x1>.) | | in pow_iter(n, x, .<1>.);; | |let pow2 = pow' 2 | |(* Here's some code to get some timings *) | | |let unstagedRunning = | Trx.timenew "unstaged running"(fun () -> pow 5 3) | |let stage1Running = | Trx.timenew "stage 1 running" (fun () -> .<fun x-> .~(pow' 5 .<x>.)>.) | |let compiling = Trx.timenew "compiling" (fun () -> .! stage1Running) | |let stage2Running = Trx.timenew "stage 2 running" (fun () -> (compiling |3)) | |let baseline = Trx.timenew "baseline" (fun () -> ()) | |(* Print all the timings *) | |let _ = Trx.print_times () | |(* Outpout of timer: |__ unstaged running ______ 2097152x avg= 7.929525E-04 msec |__ stage 1 running ________ 262144x avg= 7.248323E-03 msec |__ compiling ________________ 8192x avg= 2.320860E-01 msec |__ stage 2 running ______ 16777216x avg= 1.123075E-04 msec |__ baseline _____________ 33554432x avg= 3.921819E-05 msec |*) | |--- end ben.ml | |Walid. | |On Mon, 27 Oct 2003, Ben Kavanagh wrote: | || ||Say I have a function such as pow defined as || ||let pow n x = || let rec pow_iter (n1, x1, p1) = || if (n1 = 0) then p1 || else if (n1 mod 2 = 0) || then pow_iter(n1/2, x1*x1, p1) || else pow_iter(n1-1, x1, p1*x1) || in pow_iter(n, x, 1);; || ||and I say || ||let pow2 = pow 2 || ||Are there any ML implementations that would automatically perform ||partial evaluation to create pow2 instead of using closures, possibly ||unfolding the pow_iter call? Would Caml ever have this capability? || ||Ben || || ||------------------- ||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 || | | -- ------------------- 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] 21+ messages in thread
end of thread, other threads:[~2004-02-05 21:29 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-10-27 1:41 [Caml-list] partial eval question Ben Kavanagh 2003-10-27 7:14 ` Damien 2003-10-27 15:39 ` William Chesters 2003-10-27 18:50 ` Andrew Lenharth 2003-10-27 19:12 ` William Chesters 2003-10-27 20:08 ` Jacques Carette 2004-02-04 3:03 ` Walid Taha 2003-10-27 22:11 ` Andrew Lenharth 2004-02-04 2:59 ` Walid Taha 2004-02-04 5:53 ` Andrew Lenharth 2004-02-05 21:29 ` Walid Taha 2003-10-27 19:17 ` Yann Regis-Gianas 2003-10-28 10:46 ` William Chesters 2004-02-04 2:22 ` Walid Taha 2004-02-04 2:56 ` Walid Taha 2003-10-28 15:09 ` Dmitry Lomov 2003-10-27 15:16 ` Vincent Balat [prof Moggi team] 2004-02-04 2:51 ` Walid Taha 2004-02-04 10:26 ` Ben Kavanagh 2004-02-04 10:32 ` Ben Kavanagh 2004-02-05 21:11 ` Walid Taha
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox