From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q1DFRugm010655 for ; Mon, 13 Feb 2012 16:27:56 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai4BAJ8rOU9KfVM2kGdsb2JhbABDsAMIIgEBAQEJCQ0HFAQjgXIBAQEEEgIsARsdAQMMBgULDS4hAQERAQUBHAYTCBEJh2ObegqLcYJwhHc/iHMCBQuIOYJ7AQgCBAcICAMDBgECAwcDAQECAQoEAwQEBw4GAQMIAQQEhFWDRQSNZYdNixCDFT2EAw X-IronPort-AV: E=Sophos;i="4.73,412,1325458800"; d="scan'208";a="131167323" Received: from mail-ee0-f54.google.com ([74.125.83.54]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 13 Feb 2012 16:27:55 +0100 Received: by eekb47 with SMTP id b47so2169974eek.27 for ; Mon, 13 Feb 2012 07:27:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=jfdqmm8ZCPsSAUCeloIYxpQ19VvGca1b+ZJA01DxjMo=; b=LJqhquusabfgw7Swl5E4INtg+3ifjZPT7mlQCS0tGNCQy5ULvsj3eRvEBdZ5da7/Uq cab5+XKZW6wnPGC+ZiVh66V3RKRCSUU0O7ADZsHiQyz+LUrW8BuqLcLhnV0cbZrgA7SV ldhZ2FmForP2viVZXWeaVpSQzvl4//MtiQo6s= MIME-Version: 1.0 Received: by 10.213.29.76 with SMTP id p12mr2039705ebc.127.1329146874648; Mon, 13 Feb 2012 07:27:54 -0800 (PST) Received: by 10.213.6.195 with HTTP; Mon, 13 Feb 2012 07:27:54 -0800 (PST) In-Reply-To: References: Date: Mon, 13 Feb 2012 16:27:54 +0100 Message-ID: From: Adrien To: Philippe Veber Cc: caml users Content-Type: text/plain; charset=ISO-8859-1 Subject: Re: [Caml-list] Functional GUI programming: looking for good practices On 13/02/2012, Philippe Veber wrote: > Dear camlers, > > I'm looking for advanced examples of GUI programming in functional style. > As I'm aware there is no definitive answer on this topic, I'll gladly read > about pragmatic approaches which may fail to be fully declarative, but do > work well in practice. Lately I've been trying to write a little GUI API, > replacing all mutable values by React signals ( > http://erratique.ch/software/react), but it turns out to be more difficult > than expected, for example with layout management. In order to compute a > layout for the widgets, some information has to travel bottom up the widget > hierarchy, and some goes top down. While there is a well-founded order for > defining all signals, it's more difficult to group them in their respective > widget and still avoid mutually recursive definitions. More generally I'd > interested in good (and pragmatic !) techniques for GUI programming, with > some real life code. > Cheers, > Philippe. Since FRP is quite "new" and not well understood, I'm going to try to summarize how I understan it: it makes it possible to use functional code for a task that has typically relied on mutability, with all the benefits we're used to. I've created a lablgtk branch named "adrien/react" to get react signals out of gtk properties and react events out of gtk signals (they match quite well). Support isn't perfect but enough to test and experiment. The issue was to write the application itself: it was way too complicated and it involved many many react values which had to be somehow kept alive. It was also not very useful. The reason was that the very first thing I would do with all the events was React.E.select: I would create distinct signals only to merge them! What I've started doing instead is to have one "object" with a corresponding event: callbacks only send a message to that event and look like "send (`Foo bar)" and from then I can use match over the message in a different location in the code, typically in an FRP context. (* Warning: this is about work in-progress; it might not always make sense, might have some weird things and I might not be able to explain everything properly. *) My current application is a web browser which I want to make much more intelligent than the browsers available today. For this reason, I store web pages in a data structure which is of course purely functional. I can have several layers of data structures containing objects in the same way. My objects start with a default state and evolve (in a functional way) through a fold according to the messages they receive. Each time the state changes, two sets of callbacks are triggered: first, to change the UI; second, to update the data structure containing the object which is needed because of functional updates. I also use that last mechanism to propagate messages from the inner objects to the outter ones. One last characteristic is that I have a UI side besides the functional one. It contains a handful of things which are needed to work with GTK.I also use it to propagate messages from the outter objects to the inner ones. This is work-in-progress and some details could be improved but I think that the big picture is there. As far as I can tell, the UI and functional sides are properly separated, constraints aren't heavy and I seem to be able to get the usual qualities of ocaml in GUIs. Generally speaking, FRP is not the silver bullet for GUIs. Maybe for Haskell but definitely not for OCaml. The main reason is probably that most C libraries have a specific API which is often very imperative. OCaml provides references, mutability and objects. If you don't have a big beautiful data structure and an actual model for the state of your program, you might want to go the easy route and not use FRP but mutability everywhere. PS: for layout management, I found that using the ~packing option when creating the widgets is usually much better than #add'ing the afterwards. Hope this helps, Adrien Nader