From: striker
Subject: Data Encapsulation and printing ...
Date: 
Message-ID: <cc83dfa3c10a411a129da004255f5418@localhost.talkaboutprogramming.com>
I am new to lisp and I think it is awesome. However, I dont understand how
to encapsulate data and functions. I was hoping someone would help. 

How do I print a function/list ?
Sure I could have (print 'hello world)
but what if I want to print something else about the function/list?

I have a smalltalk background and therefore it makes sense to me to do
this:

account balance printString.

Where the account is asked for the balance and that in turn is asked for a
printable representation. 
How could I do the same in lisp ?

I guess another way of looking at the problem is how can a lisp function
address certain attributes of the argument ?

From: Matthew Danish
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <Pine.LNX.4.58-035.0407092015250.16569@unix45.andrew.cmu.edu>
On Fri, 9 Jul 2004, striker wrote:
> I am new to lisp and I think it is awesome. However, I dont understand how
> to encapsulate data and functions. I was hoping someone would help.

Don't worry too much about encapsulation right now.  Get used to mucking
around with objects and the playing around in the REPL, and you will see
why.

> How do I print a function/list ?
> Sure I could have (print 'hello world)
                    ;; ^  *note* invalid call to PRINT, unless the
                    ;; variable WORLD has a stream.
> but what if I want to print something else about the function/list?

What is a "function/list"?  There are functions, and there are lists.  You
can, for example, print a list: (print '(hello world)).  Printing a
function isn't going to be as interesting, it'll look something like this:

CL-USER> (print #'print)

#<Function PRINT #x12345678>     ;; (printed version)
#<Function PRINT #x12345678>     ;; (returned value)


> I have a smalltalk background and therefore it makes sense to me to do
> this:
>
> account balance printString.
>
> Where the account is asked for the balance and that in turn is asked for a
> printable representation.
> How could I do the same in lisp ?

(princ (balance account))

> I guess another way of looking at the problem is how can a lisp function
> address certain attributes of the argument ?

Lisp functions receive object values as parameters.  Any attributes of the
object can be operated upon by the function, of course.  I don't know what
else you could possibly mean.  Generally, attributes of objects are
read and wrote through functions, known as reader and writer functions.
There is nothing really special about them, they are just functions.  Some
reader and writer functions are combined into one name, an accessor.  Once
again, the accessor is just a normal function, but it can be used with
SETF.

Some examples:

(reader object) => value
(writer object value)  ;; sets
(accessor object) => value
(setf (accessor object) value)  ;; sets

Consider the function named FIRST that operates on lists, it is an
accessor in this sense.

(defparameter *list* (list 1 2 3 4))
(first *list*) => 1
(setf (first *list*) 0)
(first *list*) => 0
From: Gareth McCaughan
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <87zn68bsno.fsf@g.mccaughan.ntlworld.com>
James Ladd wrote:

> I am new to lisp and I think it is awesome. However, I dont understand how
> to encapsulate data and functions. I was hoping someone would help. 

(I think you're using the word "encapsulate" to mean
something different from what it normally means. That's
OK, but some people may get confused...)

> How do I print a function/list ?
> 
> Sure I could have (print 'hello world)
> but what if I want to print something else about the function/list?
> 
> I have a smalltalk background and therefore it makes sense to me to do
> this:
> 
> account balance printString.
> 
> Where the account is asked for the balance and that in turn is asked for a
> printable representation. 
> How could I do the same in lisp ?
> 
> I guess another way of looking at the problem is how can a lisp function
> address certain attributes of the argument ?

By calling a function or method that knows how to get at those
attributes; same as in Smalltalk. So if you have a function
called BALANCE that returns the balance of an account, you
could write

    (print (balance account))

much as in Smalltalk. If ACCOUNT is an instance of a structure
type defined with DEFSTRUCT and BALANCE is the name of one of its
slots, then you'll have an accessor function called something like
ACCOUNT-BALANCE, defined automatically. If ACCOUNT is an instance
of a CLOS class and BALANCE is the name of ones of its slots,
then you can have an accessor defined automatically; that's one
of the things you tell DEFCLASS.

For CLOS classes, you can get at the slots' values more directly
using the SLOT-VALUE function.

So: Just as in Smalltalk, the task of printing something about
an object is split into two: first you find that something, then
you print it.

(I have the impression that I may have missed the point of your
question. If so, please feel free to say so and explain...)

-- 
Gareth McCaughan
.sig under construc
From: Pascal Bourguignon
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <87u0wg9xae.fsf@thalassa.informatimago.com>
"striker" <··········@nospam.com.au> writes:

> I am new to lisp and I think it is awesome. However, I dont understand how
> to encapsulate data and functions. I was hoping someone would help. 
> 
> How do I print a function/list ?
> Sure I could have (print 'hello world)
> but what if I want to print something else about the function/list?

Why do you write "function/list"? A function is quite different from a
list. You can print stuff with print, princ, prin1, format,
print-object a probably a few other functions.

 
> I have a smalltalk background and therefore it makes sense to me to do
> this:
> 
> account balance printString.
>
> Where the account is asked for the balance and that in turn is asked for a
> printable representation. 
> How could I do the same in lisp ?


(princ (balance account))

Given the right declarations.


> I guess another way of looking at the problem is how can a lisp function
> address certain attributes of the argument ?

In Smalltalk, you get attributes of an argument by sending it messages.
In Lisp, you get the attributes of an argument by calling a function.
In some case, this could be a generic function that would lead to the
calling of a method.


If you want to program Smalltalk in Lisp, you'll have to use CLOS, the
object oriented layer of Common-Lisp.

(defclass a-class (super-class...)
    ( (attribute) ... ))
    
(defmethod a-method ((self a-class) other arguments)
    (another-method self (a-function other)))


But there's several differences from Smalltalk that makes the notion
of "encapsulating" not so relevant:

- the methods (generic functions) are multiple dispatching: 
  the method is not selected only by the class of one argument, 
  but by the class of all arguments!

    (defclass a ())
    (defclass b ())
    (defclass c ())

    (defmethod m ((an-a a)         (a-b b)       (a-c c)) (print 'a-b-c))
    (defmethod m ((an-a a)         (another-a a) (a-c c)) (print 'a-a-c))
    (defmethod m ((an-int integer) (another-a a) (a-c c)) (print 'i-a-c))
    ;; ...

    (m (make-instance 'a)  (make-instance 'b)  (make-instance 'c))
    (m (make-instance 'a)  (make-instance 'a)  (make-instance 'c))
    (m 42                  (make-instance 'a)  (make-instance 'c))

  So the methods don't belong to the class of their arguments, 
  they're in between...


- you have also other constructs that you could use to "encapsulate" stuff,
  like for example closures:

    (let ((some-encapsulated-data   '(hello world))   
          (an-encapsulated-function (lambda (x) (1+ x))))
        (defun guardian (operation argument)
            (cond
              ((eq operation :get-data) some-encapsulated-data)
              ((eq operation :call-fun) (apply an-encapsulated-function
                                               argument))
              ((eq operation :change-data)
                (when (string= argument "password")
                  (setf some-encapsulated-data argument))))))

    (guardian :get-data nil)
    (guardian :call-fun 42)
    (guardian :change-data '(good bye world) "password")
    (guardian :get-data nil)

  some-encapsulated-data and an-encapsulated-function are not
  accessible from outside of the guardian closure.  They're
  encapsulated inside the closure and only the closure functions can
  access them.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

There is no worse tyranny than to force a man to pay for what he does not
want merely because you think it would be good for him. -- Robert Heinlein
From: szymon
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <871xjhvad0.fsf@eva.rplacd.net>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> "striker" <··········@nospam.com.au> writes:
> 
> > I am new to lisp and I think it is awesome. However, I dont understand
> > how to encapsulate data and functions. I was hoping someone would help.
> > 
> > How do I print a function/list ?
> > Sure I could have (print 'hello world)
> > but what if I want to print something else about the function/list?
> 
> Why do you write "function/list"? A function is quite different from a
> list. You can print stuff with print, princ, prin1, format, print-object
> a probably a few other functions.

In 'some sense' function is a list (and this list can be retrived using
FUNCTION-LAMBDA-EXPRESSION), maybe striker want something like this:

CL-USER> (DEFUN FOO-FUNCTION (ARG)
	   (FORMAT T
		   "arg: ~A~2%Is my arg type-of list? ~A~2%"
		   ARG (IF (LISTP ARG) 'YES 'NO)))

CL-USER> (foo-function "bar")
arg: bar

Is my arg type-of list? NO

CL-USER> (foo-function (list 1 2))
arg: (1 2)

Is my arg type-of list? YES

CL-USER> (foo-function #'foo-function)
arg: #<Interpreted Function FOO-FUNCTION {587A6599}>

Is my arg type-of list? NO

CL-USER> (foo-function (function-lambda-expression #'foo-function))
arg: (LAMBDA (ARG)
       (BLOCK FOO-FUNCTION
         (FORMAT T
                 arg: ~A~2%Is my arg type-of list? ~A~2%
                 ARG
                 (IF (LISTP ARG) 'YES 'NO))))

Is my arg type-of list? YES

CL-USER> (compile 'foo-function)
; Compiling LAMBDA (ARG): 
; Compiling Top-Level Form: 
FOO-FUNCTION
NIL
NIL
CL-USER> (foo-function #'foo-function)
arg: #<Function FOO-FUNCTION {587C0029}>

Is my arg type-of list? NO

CL-USER> (foo-function (function-lambda-expression #'foo-function))
arg: (LAMBDA (ARG)
       (BLOCK FOO-FUNCTION
         (FORMAT T
                 arg: ~A~2%Is my arg type-of list? ~A~2%
                 ARG
                 (IF (LISTP ARG) 'YES 'NO))))

Is my arg type-of list? YES

;; ---------------------------------------------------------

Regards, Szymon.
From: Karsten Poeck
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <boOHc.3445$r4.124356@news-reader.eresmas.com>
Hello,
printString should be the same as write-to-string.
account balance printString therefore is equivalent to
(write-to-string (balance account))

If you want to customise write-to-string use print-object.
A lisp function adresses arguments of the arguments as in SmallTalk via
accessors.

Try the following example in the listener (= SmallTalks workspace)

(defclass account ()
  ((balance :accessor balance :initarg :balance)))

(defparameter *account* (make-instance 'account :balance 23))

(write-to-string *account*)
(write-to-string (balance *account*))

;;; to print the balance in account
(defmethod print-object ((me account) stream)
  (print-unreadable-object (me stream :type t :identity t)
    (princ "Balance:" stream)
    (princ (balance me) stream)))

saludos

Karsten

"striker" <··········@nospam.com.au> wrote in message
·····································@localhost.talkaboutprogramming.com...
> I am new to lisp and I think it is awesome. However, I dont understand how
> to encapsulate data and functions. I was hoping someone would help.
>
> How do I print a function/list ?
> Sure I could have (print 'hello world)
> but what if I want to print something else about the function/list?
>
> I have a smalltalk background and therefore it makes sense to me to do
> this:
>
> account balance printString.
>
> Where the account is asked for the balance and that in turn is asked for a
> printable representation.
> How could I do the same in lisp ?
>
> I guess another way of looking at the problem is how can a lisp function
> address certain attributes of the argument ?
>
>
From: striker
Subject: Re: Data Encapsulation and printing ...
Date: 
Message-ID: <501895e131df55476b32fdaa559a4201@localhost.talkaboutprogramming.com>
Thankyou to all respondents. Very clear now thanks.