[racket-users] Re: Operations that create objects

2016-12-19 Thread NeverTooOldToCode
Thank you for the examples and clarification.

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


Re: [racket-users] Re: Operations that create objects

2016-12-16 Thread Gustavo Massaccesi
Two examples:

#lang racket

(define (create-function-that-show-number n)
  (display "*")
  (lambda ()
(displayln n)))

;Create the function
(define f7 (create-function-that-show-number 7))
;Use it
(displayln "Hello")
(f7)
(displayln "World!")

;---
;Something more complex

;Create and store the functions in a vector
(define v (vector (create-function-that-show-number 2)
  (create-function-that-show-number 1)
  (create-function-that-show-number 0)
  (create-function-that-show-number 6)))
;Select one of them at random
(define r (vector-ref v (random 4)))
;Use it
(r)

;Gustavo


On Fri, Dec 16, 2016 at 2:15 PM, Jan Hondebrink  wrote:
> Thank you so much. This is extremely helpful and instructive.
>
> One thing I don't understand: how do you call or access an inner function
> after its outer function has completed?
>
> On Fri, Dec 16, 2016 at 5:41 AM, George Neuner  wrote:
>>
>> On Thu, 15 Dec 2016 06:03:54 -0800 (PST), NeverTooOldToCode
>>  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 

Re: [racket-users] Re: Operations that create objects

2016-12-16 Thread Philip McGrath
The outer function must return the inner function (or otherwise make it
reachable, perhaps inside some data structure). For example:

> (define (make-counter init)
(define (counter)
  (set! init (add1 init))
  init)
(displayln "Making a counter!")
counter)
> (define count-from-five
(make-counter 5))
Making a counter!
> (count-from-five)
6
> (count-from-five)
7
> (count-from-five)
8
> (define count-from-two
(make-counter 2))
Making a counter!
> (count-from-two)
3
> (count-from-five)
9


On Fri, Dec 16, 2016 at 11:15 AM, Jan Hondebrink 
wrote:

> Thank you so much. This is extremely helpful and instructive.
>
> One thing I don't understand: how do you call or access an inner function
> after its outer function has completed?
>
> On Fri, Dec 16, 2016 at 5:41 AM, George Neuner 
> wrote:
>
>> On Thu, 15 Dec 2016 06:03:54 -0800 (PST), NeverTooOldToCode
>>  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 

Re: [racket-users] Re: Operations that create objects

2016-12-16 Thread Jan Hondebrink
Thank you so much. This is extremely helpful and instructive.

One thing I don't understand: how do you call or access an inner function
after its outer function has completed?

On Fri, Dec 16, 2016 at 5:41 AM, George Neuner  wrote:

> On Thu, 15 Dec 2016 06:03:54 -0800 (PST), NeverTooOldToCode
>  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 a topic in the
> Google Groups "Racket Users" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/racket-users/3oZ0U0_0E94/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop 

[racket-users] Re: Operations that create objects

2016-12-15 Thread George Neuner
On Thu, 15 Dec 2016 06:03:54 -0800 (PST), NeverTooOldToCode
 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.