From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=AWL,SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 7E27BBC0A for ; Thu, 21 Dec 2006 04:36:20 +0100 (CET) Received: from wx-out-0506.google.com (wx-out-0506.google.com [66.249.82.238]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id kBL3aJtg019425 for ; Thu, 21 Dec 2006 04:36:20 +0100 Received: by wx-out-0506.google.com with SMTP id i26so2323750wxd for ; Wed, 20 Dec 2006 19:36:19 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=ZcZ2e1S1gi/8C0RSCtHb9dA40UFFjUje6rfHfymeavDI64BgripsdfiZ9NfTxBAKhLVEgsXms4PvlQs6v4RNhft432FFOMj9J/bWLTs87Gajgm1jT6u7KF7Ew+v3opVOYamEkqmcBClo7/nVnTee0xZY9iIqjWdv9gWd+mgWW7I= Received: by 10.90.78.9 with SMTP id a9mr8204017agb.1166672179214; Wed, 20 Dec 2006 19:36:19 -0800 (PST) Received: by 10.90.115.1 with HTTP; Wed, 20 Dec 2006 19:36:19 -0800 (PST) Message-ID: <875c7e070612201936y495a1949qa493fb71a1f4a992@mail.gmail.com> Date: Wed, 20 Dec 2006 22:36:19 -0500 From: "Chris King" To: "Gabriel Kerneis" Subject: Re: [Caml-list] Functional Reactive GUI for O'Caml Cc: caml-list@yquem.inria.fr In-Reply-To: <20061220180028.48b36a26@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <875c7e070612200738t6aa99d08nc7a9ec741467ec4d@mail.gmail.com> <20061220180028.48b36a26@localhost> X-j-chkmail-Score: MSGID : 458A0133.000 on discorde : j-chkmail score : X : 0/20 1 0.000 -> 1 X-Miltered: at discorde with ID 458A0133.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; o'caml:01 syntax:01 one-liner:01 defines:01 expr:01 expr:01 o'caml:01 pointer:01 hbox:01 hbox:01 vbox:01 vbox:01 vertically:01 gui's:01 breakdown:98 On 12/20/06, Gabriel Kerneis wrote: > It might have been clearer if I had read a quick tutorial or how-to > before. But your question targeted newbies, so let me give you a > total newbie's answer : I just can't get it ;-) You have a very good point :) nothing's intuitive unless it's familiar, which I admit the syntax (especially lift) is not. I intend to post some examples as well as a tutorial in the next few weeks, but for the time being here is a quick breakdown of the above example (with a few math fixes :P): > open Fr > open FrGui Fr is the library containing funcitons to create functional reactive expressions; FrGui contains definitions of all the GUI widgets. > let float_view f = text_view (lift (string_of_float @f)) This one-liner defines the float_view widget in terms of the text_view widget. Ignoring the definition (which should make more sense later), it's simply a function which creates a widget which displays the time-varying floating-point value f. > let _ = > let temp_box, temp = spin_box 20. in spin_box is a function which creates a widget (temp_box) which allows the user to input a floating-point value (in this case, the temperature we want to convert). Here 20 is given as its initial value. The current value of temp_box is stored in temp. This value can change with time and is called a "behavior" (and has the type float behavior). > let fahrenheit = lift (@temp *. 1.8 +. 32.) Because temp is not a float but a float behavior, we must use a special construct to access it. lift (expr) allows us to access values contained in behaviors and to create new ones. Inside of expr (which is otherwise a normal O'Caml expression), we can use the form @expr to reference a behavior (think of this like dereferencing a pointer in C). Here, fahrenheit is a behavior which is always equal to the value of (temp *. 1.8 +. 32.). Whenever temp changes, so does fahrenheit. > and celsuis = lift ((@temp -. 32.) /. 1.8) in Here, we similarly define celsius as a float behavior which is dependent on the current value of temp. > let main_window = window > ~title: "Temperature converter" > (hbox [ > hbox [label "Convert "; temp_box; label " to:"]; > vbox [ > hbox [label "degrees Fahrenheit: "; float_view fahrenheit]; > hbox [label "degrees Celsius: "; float_view celsius]]]) in Here we define the main window. hbox, vbox, and label are all functions which create widgets. hbox and vbox pack lists of widgets horizontally and vertically, and label creates a text label. temp_box is the widget instance we defined above, which allows the user to enter the value of temp. We also create two instances of the float_view widget, to display the values of fahrenheit and celsius. > run_dialog (main_window, main_window#close) This incantation displays main_window and enters the GUI's main loop until the window's close button is clicked. The end result is a window with a spin box into which the user can input a temperature. That temperature is instantly converted into both Fahrenheit and Celsius and displayed in two other text boxes (the float_views) in the window. Hopefully this description helped more than it confused... if it did more of the latter then I'll try to post a proper tutorial on the O'Caml RT website as soon as possible, since one is in order anyway. Thanks for you input :) - Chris