Version franaise
Home About Download Resources Contact us
Browse thread
The Implicit Accumulator: a design pattern using optional arguments
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Quc_Peyrot <chojin@l...>
Subject: Re: [Caml-list] The Implicit Accumulator: a design pattern using optional arguments

On Jun 27, 2007, at 6:39 PM, Thomas Fischbacher wrote:

>
> Quc Peyrot wrote:
>
>>> 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 example: what you can do quite easily in LISP is to introduce
> a global lookup thingy MEMOIZATIONS (say, a list of hash tables
> or something like that) and define macros WITH-LOCAL-MEMORY and
> MEMOIZING where WITH-LOCAL-MEMORY defines a new dynamic
> memoization scope, and MEMOIZING wraps up a few functions in such
> a way that they use memoization. Result: we can have both
> memoization on functions as well as defined behaviour with respect
> to when memoized values are being forgotten again (namely, when
> we are finished with the evaluation of the form
>
> (WITH-LOCAL-MEMORY ...)).
>
> Note that functions dynamically called from functions lexically scoped
> inside this construct will ALSO use the same local memoization table!
> In other words, when control flow exits the WITH-LOCAL-MEMORY block
> (in whatever way it does so), our memoizing information is returned to
> precisely the state it was in before we entered that block. That is
> the magic of dynamic scoping.

I'm not sure I understand why we can't do it in ocaml, but I
would probably need to try to implement it to see why.
I mean if we implement something along the lines:
let memo f =
   let hash = ...

then can't we have the same feature using "let in" ?

let memoized_f = memo f in
   let memoized_f = memo f in
     (* when we leave this scope, we should get back the first table *)

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

[...]

> With this, I suppose, a proper book on both "functional optimization
> strategies" and "ideas that help you to overcome mental barriers with
> respect to what's possible when one can shape the language" would be
> useful, not so much to "teach specific patterns", but to teach people
> how to overcome their mental blockades and learn how to use their
> phantasy to do marvelous things by shaping language. In the
> Permaculture community, there is this proverb that "yield is
> limited only by imagination". I think this holds just as much for
> functional and in particular metalinguistic programming.

I wanted to prevent from reducing my comment to the "functional" part.
The design patterns discussed in this thread has more to do with ocaml
itself (or the garbage collector for my example). I've seen plenty of  
tutorials
and articles about functional languages but they often expose the same
things and lack (from my point of view again, please keep in mind
that runtime/memory efficiency is important to me) on the efficiency  
side
(especially the memory one, often ignoring as well the big runtime  
hit you
can have due to the allocations).

Writing concise and elegant code is very important to me, really. I hate
dirty ugly code, but I'm not willing to sacrifice the efficiency.  
That's why
I really like OCaml, it is very powerful but allows us to efficient  
code...
as long as you actually do understand how the compiler is going to
process your code. And that's the book I wish I could have. We can call
that design pattern or industry best practices. I just want to be  
able to
write real-life code (and not necessarily scientific-oriented code,  
sorry
Jon Harrop ;) ) without having to re-discover all these best practices
(which might be very natural for someone with a deeper understanding
of all the different features a specific language provides). I don't  
think
the only subtle part of OCaml is the fact that it is a functional  
language.
There is really more to it, IMHO.

> (I have been planning for years to eventually write up some
> lengthier introductory text on metalinguistic techniques, but so
> far only managed to write a few articles and give some short courses
> on the subject...)

Keep us posted ;)

>> 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.
>
> Languages such as OCaml are not "intended to hide low-level details".

Sorry, I'm not really good with words, I indeed wanted to talk about (2)

>
> Rather, there are (at least) two very different notions of  
> "programming"
> around:
>
> (1) Putting information into a mechanically behaving system in order
>     to get some desired behaviour. (This is what asm/C/C++ is about,
>     but actually, this even is a much broader notion that also  
> includes
>     e.g. this: http://amasci.com/amateur/mirror.html)
>
> (2) Formalizing some "mental process" in such a way that one can
>     then use stringent reasoning to analyze its properties. (This is
>     what, in essence, functional programming is about.)
>
>
> Evidently, the more advanced you get, the more important the second
> point of view becomes.

(2) is very important to me, but as said earlier, I often found while  
reading
articles (functional programming) that highly category-2 oriented people
tend not to care at all (or barely) about real-life runtime of the  
program.
Writing correct code is not good enough, I need to be able to execute it
within my life-time (I know, I'm a bit provocative here ;) )

We often oppose category-2 oriented people with category-1 oriented  
people.
I think we can meet somewhere in a middle, and the book we talked about
would certainly help.

But yes, I agree that, sometimes, the design pattern is here to solve  
a problem
the language itself should solve, but that's not always the case.

-- 
Best Regards,
Quc