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=0.9 required=5.0 tests=AWL,RCVD_IN_WHOIS_BOGONS autolearn=disabled version=3.1.3 Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 19B7CBC69 for ; Wed, 28 Mar 2007 19:46:06 +0200 (CEST) Received: from sdmx1.scea.com (sdmx1.scea.com [160.33.44.36]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l2SHk3fM014650 for ; Wed, 28 Mar 2007 19:46:05 +0200 Received: from edenfox.989studios.com (edenfox.989studios.com [160.33.45.60]) by sdmx1.scea.com (8.13.6/8.13.1) with ESMTP id l2SHjvEU027108; Wed, 28 Mar 2007 10:45:57 -0700 X-Envelope-From: X-Envelope-To: X-Envelope-To: Received: from postal1-dog.naughtydog.com (testmail.naughtydog.com [10.15.0.5]) by edenfox.989studios.com (8.13.7/8.13.7/SCEAint-1.0) with ESMTP id l2SHjj6J023176; Wed, 28 Mar 2007 10:45:53 -0700 Received: from [127.0.0.1] ([150.0.6.116]) by postal1-dog.naughtydog.com with Microsoft SMTPSVC(6.0.3790.1830); Wed, 28 Mar 2007 10:44:55 -0700 Message-ID: <460AA8D8.9000209@naughtydog.com> Date: Wed, 28 Mar 2007 10:41:44 -0700 From: Pal-Kristian Engstad User-Agent: Thunderbird 1.5.0.10 (Windows/20070221) MIME-Version: 1.0 To: Loup Vaillant Cc: caml-list@inria.fr Subject: Re: [Caml-list] How must we teach lexical scope? References: <6f9f8f4a0703280059m5b9af3a1t3a9541b772af98bb@mail.gmail.com> In-Reply-To: <6f9f8f4a0703280059m5b9af3a1t3a9541b772af98bb@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-OriginalArrivalTime: 28 Mar 2007 17:44:55.0872 (UTC) FILETIME=[CC1ED400:01C77160] X-Scanned-By: MIMEDefang 2.48 on 160.33.44.36 X-Scanned-By: MIMEDefang 2.48 on 160.33.45.59 X-BorderEnvelope-To: X-BorderEnvelope-To: X-Miltered: at discorde with ID 460AA9DB.001 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; nomenclature:01 mutable:01 mutable:01 val:01 ocaml:01 ocaml:01 val:01 pointer:01 pke:01 syntax:01 beginner's:01 bug:01 blog:98 dog:98 beginners:01 I've probably got the nomenclature wrong, but this is how I would explain it. I do think this is an advanced topic though - it definitely does not belong in an introductory programming course. Caml, and many other languages, has the interesting concept of being able to create functions on-the-fly. That is to say, you can define an auxiliary helper-function within the function you are working on. This is a very powerful concept, because it allows you to re-factor code quite easily. Somewhere along the line, you see that: "Oh, I need to do .... another time, this time using variable ..." If this happens, you can simply create a sub-function within the function, and start using that. Now, a function needs input parameters to work. However, it would be quite tedious to have to specify all the parameters for all your sub-functions. Therefore, Caml lets you use variables from the "outside", or the outer scope, as we say. An example: # type env = { mutable scale : int; mutable offset : int }; type env = { scale : int; offset : int; } # let work env a b = let linear x = env.scale * x + env.offset in linear a + linear b ;; val work : env -> int -> int -> int = # As you can see in this contrived example, we introduced a new function linear, since we needed to use that calculation twice. But notice also that we did not specify the "env" variable as an input to linear. Thus, functions in OCaml are slightly more complicated than appears at first sight. Now, in OCaml it is also possible to return functions. For instance, we could change the above function to the following: # let work' env = let linear x = env.scale * x + env.offset in (fun a b -> linear a + linear b) ;; val work' : env -> int -> int -> int = So, when you call "work' env", you get returned a function that adds together the results of the "linear" functions. [Note: For the observant reader, work' is actually the same function as work.]. Example: # let env1 = { scale = 0; offset = 1 };; val env1 : env = {scale = 0; offset = 1} # let fun = work' env1;; val fun : int -> int -> int = # fun 1 2;; - : int = 2 # env1.scale <- 1;; - : unit = () # fun 1 2;; - : int = 5 The first call to fun works, because: fun 1 2 = linear 1 + linear 2 = (env.scale * 1 + env.offset) + (env.scale * 2 + env.offset) = (0*1+1)+(0*2+1) = 2. But, in the second call to fun, the environment has changed, now env.scale is 1, so fun 1 2 = linear 1 + linear 2 = (1*1+1)+(1*2+1) = 5. So, to conclude. For this to work, the function fun can not only depend on the input arguments. The function must retain a pointer to the environment that was used to create it. We call this a "closure". Scoping in this respect is important, because it tells us which external variables are captured by the function. This is cool, because it means that we don't have to use "function objects" (C++) or anything like that. Flame on, PKE. Loup Vaillant wrote: > My brother is currently learning Camllight at the Toulouse 3 > university, France. Five years ago, I followed the same course. > > I don't understand the way were are taught lexical scope. Our > professors used "environments", where free variable would suffice. > (An environment is the set of defined values at a given time. The > environment of a value is the environment of when this value is > defined.) > > -> They talk about closures, even in the case of pure functional > style, even in the absence of free variable (except the built in > constructions, such as '+'). > -> They take hours and hours of boring an silly looking exercises > about environment, so we can understand how important environments > are.(we even had to learn a specific syntax to talk about them). > -> The promised power of the language is completely overlooked. Even > the crippled Pascal on my calculator looked more powerful. > > Luckily, I had later a professor, who showed us the real power of > Caml. He didn't talked about environments. > > So here are a few questions: > -> Is lexical scope that important when learning pure functional > programming? > -> Are environments helpful (even the slightest bit) when teaching > lexical scope? > -> Where does this idea come from? I have not read a single book, as > single article nor blog talking about environments. > -> How can we teach lexical scope? Is there a simple solution, the > kind of a first year student can understand in less than an hour? > > Thanks, > Loup > > _______________________________________________ > Caml-list mailing list. Subscription management: > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > Archives: http://caml.inria.fr > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > -- Pål-Kristian Engstad (engstad@naughtydog.com), Lead Programmer, ICE team, Naughty Dog, Inc., 1601 Cloverfield Blvd, 6000 North, Santa Monica, CA 90404, USA. Ph.: (310) 633-9112. "Most of us would do well to remember that there is a reason Carmack is Carmack, and we are not Carmack.", Jonathan Blow, 2/1/2006, GD Algo Mailing List