caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Quôc Peyrot" <chojin@lrde.epita.fr>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] The Implicit Accumulator: a design pattern using optional arguments
Date: Wed, 27 Jun 2007 17:06:51 +0200	[thread overview]
Message-ID: <F2BC247F-45B1-4BD3-A006-D214D635ABC6@lrde.epita.fr> (raw)
In-Reply-To: <46826C69.5060802@functionality.de>


On Jun 27, 2007, at 3:55 PM, Thomas Fischbacher wrote:

> Quôc Peyrot wrote:

[...]

> > let encrypt ?encrypted str =
> >   let len = String.length str in
> >   let result = match encrypted with
> >     | None -> String.create len
> >     | Some s -> s
> >   in
> >   (* ... *)
> >   result
>
>> Which gave me more than a 2x speedup while still being able to  
>> call a  simple:
>> let encrypted = encrypt str
>> during normal usage
>
> I use this strategy a lot and found that it eventually pays to use
> uniform conventions for that: all my functions that can benefit from
> having space pre-allocated where to write a result to use ?target
> as their very first named optional argument (and also return that
> target buffer afterwards).

Ah, thanks, I was actually trying to find a common name too, but
didn't really like "result". "target" is nice :p

> However, unless I am mistaken, I fear that this also does introduce
> some intrinsic/unavoidable inefficiency, as providing a ?target
> argument will (presuambly?) require dynamic consing of a <thingy>
> option cell - so not a good idea for a very small function that is
> called very very often.
>
> There are many many way more advanced tricks one would want to play
> with the idea of "allocating buffers at the appropriate time". For
> example, if this were LISP, one could often use dynamically scoped (in
> the sense of (declare (dynamic-extent buffer-stack))) contextual
> variables for great benefit (and these gory details often can also be
> hidden quite conveniently under a few (maybe even in-place macrolet)
> macros...), but unfortunately, OCaml does not support anything like
> that. Of course, re-entrantness of your code may always become an
> issue if you move buffers to higher scopes.

I didn't get that part, but I'm not familiar with Lisp.

> One thing OCaml can do better than, say, CMU CL, is to define globally
> visible functions that depend on some otherwise inaccessible context,
> as in the following example:
>
> let float_factorial =
>   let _known_factorials = ref [|1.0;1.0;2.0;6.0;24.0;120.0;720.0|] in
>   (fun n ->

I encountered this pattern today while reading extlib's OptParse.Opt  
code:

let value_option metavar default coerce errfmt =
   let data = ref default in
   {
     option_metavars = [metavar];
     option_defhelp = None;
     option_get = (fun _ -> !data);
     option_set_value = (fun x -> data := Some x);
   (*...*)

I was a little bit surprised at first that we could do that  
(let ...ref...  in) but it's really nice.
To me it seems that the common feature which enables us to do all  
these tricks is the fact that we have a garbage collector (correct me  
if I am wrong). It's really powerful, and I find it fascinating.

I mean, for someone like me, with quite some experience in the asm/c/c 
++ world (i.e. a garbage collector-less world) but not much in other  
languages, it's easy to naively think of a garbage collector as a  
fancy feature to prevent from having to call "free/delete". But I'm  
starting to realize there is a whole new set of powerful design  
patterns which come along. It has been said multiple times on this  
mailing list, but I think we really miss a book about these design  
patterns and optimization tricks often specific to a given (or a set  
of) feature (functional, lazy computations, garbage collector...).

I find it ironical that high-level languages (such as ocaml) are  
intended (of course that's my interpretation of it) to hide low-level  
details and give you more expressiveness in your code, which should  
naively make you more productive, and make it easier to program  
something. But requires therefore tons of new knowledges and deep  
understanding of advanced concepts to be able to actually code  
efficient (runtime and memory-wise) code.

I mean, in asm/c/c++ there isn't much feature to learn, you pretty  
much do everything yourself. It's therefore quite easy (comparing to  
OCaml) to actually see what is efficient and what is not. OCaml is so  
high-level, and is doing so much for you, that you really need to  
learn a lot more about compilation theory to be able to actually feel  
at ease when you are looking for efficiency without giving up too  
much code elegance. But don't get me wrong, I love it, it's  
fascinating, but still ironical from my point of view.

> Other advanced optimization techniques that can be used for benefit
> in very specialized situations include (explicit) continuation coding:
> rather than returning a value (e.g. a tuple), you take as an argument
> a function to which you then pass on your return value(s). This is  
> quite
> useful whenever "execution flow branches out into multiple paths that
> have to be taken", and may sometimes (though rarely) also be used for
> good as a poor man's VALUES/MULTIPLE-VALUE-BIND substitute.

I didn't get that part at all. I think I would need an example to  
understand
why it is interesting to pass the function instead of just returning  
the tuple
and processing it.

-- 
Best Regards,
Quôc




  reply	other threads:[~2007-06-27 15:06 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-27 12:14 Jon Harrop
2007-06-27 13:18 ` [Caml-list] " Quôc Peyrot
2007-06-27 13:53   ` Jon Harrop
2007-06-27 14:18     ` Thomas Fischbacher
2007-06-27 15:09     ` Quôc Peyrot
2007-06-27 15:28     ` Mattias Engdegård
2007-06-27 15:38       ` Robert Fischer
2007-06-27 15:48         ` Mattias Engdegård
2007-06-27 16:01           ` Robert Fischer
2007-06-27 16:01           ` Mattias Engdegård
2007-06-27 18:06           ` Jon Harrop
2007-06-27 18:31             ` Brian Hurt
2007-06-27 19:56               ` skaller
2007-06-27 20:17               ` Jonathan Bryant
2007-06-27 22:57               ` Jon Harrop
2007-06-27 16:53     ` Hash-consing (was Re: [Caml-list] The Implicit Accumulator: a design pattern using optional arguments) Daniel Bünzli
2007-06-30  8:19     ` [Caml-list] The Implicit Accumulator: a design pattern using optional arguments Pierre Etchemaïté
2007-06-27 13:55   ` Thomas Fischbacher
2007-06-27 15:06     ` Quôc Peyrot [this message]
2007-06-27 15:53       ` Jon Harrop
2007-06-28 11:01         ` Thomas Fischbacher
2007-06-28 11:32           ` Jon Harrop
2007-06-28 11:42             ` Joel Reymont
2007-06-28 12:08               ` Jon Harrop
2007-06-28 13:10                 ` Quôc Peyrot
2007-06-28 13:35                   ` Thomas Fischbacher
2007-06-28 12:59             ` Thomas Fischbacher
2007-06-28 13:05               ` Jon Harrop
2007-06-28 13:33                 ` Thomas Fischbacher
2007-06-28 14:43                   ` Jon Harrop
2007-06-28 16:01                     ` Thomas Fischbacher
2007-06-28 17:53                       ` Jon Harrop
2007-06-27 16:39       ` Thomas Fischbacher
2007-06-27 19:26         ` Quôc Peyrot
2007-06-28 11:39           ` Thomas Fischbacher
2007-06-28 14:44             ` Jon Harrop
2007-06-28 16:03               ` Thomas Fischbacher
2007-06-28 17:20                 ` Dirk Thierbach
2007-06-28 22:12                   ` Thomas Fischbacher
2007-06-29  1:10                     ` Jon Harrop
2007-06-29 10:55                       ` Thomas Fischbacher
2007-06-29  6:12                     ` Dirk Thierbach
2007-06-27 17:16       ` Book about functional design patterns Gabriel Kerneis
2007-06-27 17:48         ` [Caml-list] " Jon Harrop
2007-06-27 19:33           ` Quôc Peyrot
2007-06-27 19:30         ` Quôc Peyrot
2007-06-27 19:48           ` Brian Hurt
2007-06-27 20:04             ` Quôc Peyrot
2007-06-27 20:35               ` Brian Hurt
2007-06-27 20:55                 ` Quôc Peyrot
2007-06-27 20:58                   ` Pal-Kristian Engstad
2007-06-27 21:18                     ` Quôc Peyrot
2007-06-27 21:18                       ` Pal-Kristian Engstad
2007-06-27 21:34                         ` Quôc Peyrot
2007-06-27 22:13                           ` Pal-Kristian Engstad
2007-06-27 15:18     ` [Caml-list] The Implicit Accumulator: a design pattern using optional arguments Jon Harrop
2007-06-27 16:44       ` Thomas Fischbacher
2007-06-27 18:17         ` Jon Harrop
2007-06-28 11:18           ` Thomas Fischbacher
2007-06-29 13:15     ` Bill Wood

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=F2BC247F-45B1-4BD3-A006-D214D635ABC6@lrde.epita.fr \
    --to=chojin@lrde.epita.fr \
    --cc=caml-list@yquem.inria.fr \
    /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;
as well as URLs for NNTP newsgroup(s).