On Thu, 15 Dec 2016 06:03:54 -0800 (PST), NeverTooOldToCode
<jrhondebr...@gmail.com> wrote:

>Racket Reference section 1.1.5 states: "Operations that create
>objects, such as vector, add to the set of objects" followed
>by a nice and instructive step-by-step evaluation example.
>Further on, lambda is used as another example of an operation
>creating an object.
>
>How can I tell which operations create objects?

It is safe to assume that most operations will create new objects.  If
you're just beginning to learn the language, it isn't something you
need to worry about yet.


Racket is in the Lisp family of languages: most types of data are
"boxed".  Boxed data is stored in an object on the heap, together with
a "tag" that describes the type of the data.  Variables in your
program will contain references (pointers) to boxed values.

Racket does not distinguish between the boxed object and the reference
to it.  Any time you try to look at the reference, you see the data
inside the box instead.  In this way Racket is _not_ like other
languages in which pointers and/or references can examined and/or
manipulated separately.

The above is a bit simplistic: some types like characters and small
integers are "immediate" - stored directly in variables (or list
nodes, array slots, structure fields, etc.).  But it is safe to assume
that *most* types of data will be an object on the heap.


When you get to the point of needing to optimize programs for speed,
Racket does offer typed vectors and arrays which store numeric values
unboxed.  There is also a typed version of Racket which tries to
eliminate boxing data as much as is possible.



Explaining why lambda creates an object is a bit more complicated.

Lisp family languages, including Racket, support the concept of
"nested" functions: in other words, they permit functions to be
declared inside the scope of other functions.
[If you're familar with Algol or Pascal, etc., in general the nested
functions in Racket will act very similarly.]

Inner functions can access local variables of the outer functions that
enclose them.  This type of access is known as "non-global,
non-local", usually shortened in the literature to just "non-local".
It requires having a way to locate the variables that belong to the
enclosing functions.

Now, Racket also is in the Scheme language family.  In Scheme,
functions are "1st class", which means that they may create and return
new functions, be stored in data structures, be passed as arguments to
other functions, etc.

In particular, Scheme - and Racket - allows the creation of inner
functions that persist and can be called *after* their outer functions
have completed.  

Executing a function requires not just its code, but also external
data needed by the function: it's so-called "environment".  In many
languages, the environment consists only of global data and arguments
passed directly to the function - but the environment of an inner
function includes local variables of enclosing outer functions.

If an inner function is to persist after its enclosing outer function
has completed, the local variables of the outer function must *also*
persist.

To accomplish this, lambda creates an object called a "closure".  The
closure contains data defined by the outer function(s) that is needed
by the inner function, together with a pointer to the code of the
inner function.  The closure, being an object itself, can be
referenced by other data structures, passed as an argument, etc.

Closures permit functions to have persistent private data.  By sharing
closures, multiple functions can share data without the data being
defined globally.


If this sounds quite like the objects in your favorite OO language ...
well, it *is*.  The major difference is that closures are more general
than objects in most OO lanuages.   Lambda permits ad hoc associations
of data and code, without having to define classes, or clone a
"prototype" object, or worry about inheritence hierarchies.


Hope this helps,
George

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to