Context or FOOP

Started by newBert, November 29, 2007, 10:49:35 AM

Previous topic - Next topic

newBert

I want to create two distinct objects from the same class. I can do it with context but I don't manage with FOOP.



Examples :


(context 'Point)
(set 'x 0 'y 0)
(context MAIN)

(new Point 'p1)
(set 'p1:x 3 'p1:y 4)
(new Point 'p2)
(set 'p2:x 3 'p2:y 4)
(println (= p1 p2)) ; => nil : p1 and p2 are two distinct objects

(set 'p3 p1)
(println (= p1 p3)) ; => true : p1 and p3 refer to the same object

; this demonstrates that
(set 'p1:x 7)
(println p3:x) ;=> 7



;; with FOOP :

(define (Point:Point x y)
(list Point x y))

(set 'p1 (Point 3 4))
(set 'p2 (Point 3 4))
(println (= p1 p2)) ; => true

(set 'p3 p1)
(println (= p1 p3)) ; => true

(set 'p1 (Point 7 4))
(println p1) ;=> (Point 7 4)
(println p3) ;=> (Point 3 4)


Other question : how can I get a value from an object with FOO ?

With 'Context' :
(context 'Point)
(set 'x 0 'y 0)
(context MAIN)

(new Point 'p1)
(set 'p1:x 3 'p1:y 4)

(println p1:x) ; => 3


With 'FOOP', how to get/print p1:x ?
(define (Point:Point x y)
(list Point x y))

(set 'p1 (Point 3 4))

(println p1) ;=> (Point 3 4)

I think I missed a stage ?
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>

Lutz

#1
(define (Point:Point x y)
   (list Point x y))

(define (Point:x obj) (obj 1))

(set 'p1 (Point 3 4))


(:x p1) => 3


Lutz

cormullion

#2
Don't quote me (I've been following along at the back of the class but falling asleep occasionally) but



(println (= p1 p2)) ; => true



is perhaps telling you that the points have the same co-ordinates...

Lutz

#3
Yes, that is the nice thing of representing objects as lists, you can just use '=' to compare them.



Lutz

m i c h a e l

#4
Hi newBert!



Even though Lutz already gave you the solution for writing a getter, let me encourage you to design your objects to keep all access within the object's own methods.



Object accessors considered harmful ;-)



Don't get me wrong, if you need accessors, then by all means use them. But a solution captured as a method would still be better.



For instance, in your example, you wanted to get a point's x attribute. But the reason you wanted it was to print it. So instead, we could write a Point method to print points:


(define (Point:println p) (println (p 1) "@" (p 2)))
(:println (Point 7 4)) ; prints 7@4


Notice that all access to the object is occurring within the object's own method and that it's being done using implicit indexing. Implicit indexing mimics the object's list representation, with 1 being the first attribute, 2 the second, and so on.



Also notice that defining this method within a context (between a (context 'symbol) ... (context MAIN) pair) requires you to fully qualify the println:


(context 'Point)
(define (Point:println p) (MAIN:println (p 1) "@" (p 2)))
(context MAIN)


I tend to define methods within the MAIN context for this and other reasons.



m i c h a e l

newBert

#5
Thanks for those insructive replies :) (that I store at once)



I forgot a little that I must view an object as a list (rather than as a context). Now all is clearer for me. I see the the logic of the thing !



Moreover objects p1 and p2 are distinct even if they are equal, in relation to their coordinates.



Thank you.

I go back to my FOOP experiments

;)
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>

newdep

#6
Quote from: "Lutz"(define (Point:Point x y)
   (list Point x y))

(define (Point:x obj) (obj 1))

(set 'p1 (Point 3 4))


(:x p1) => 3


Lutz




Lutz,



This bring me actualy to a function/cell called 'SELF.

Where 'self represents its own symbol or function.



Now i tried to create a 'self function to use inside contexts but

thats impossible ;-) because you endup having a context symbol.



It all fits but does not result in what i seek.

Here an example of what i seek.



So instead of wrting this ->

(define (Point:Point x y) (list Point x y))



I would like to write this ->

(define (Point:Point x y) (list self x y))



where 'self represents the name of the symbol of the context.

thus in point:here its the 'here.



But because (name (context)) returns a STRING, "here", so its impossible

to nest that lambda into this. because making it a symbol again

would give me point:here and not 'here. ;-)





Any ideas?
-- (define? (Cornflakes))

m i c h a e l

#7
Hi newBert!



A while back, I experimented with storing the symbol used to first reference the object in order to make the object self-aware. Something like this:


(set 'a '(apple a "red" "large"))
(set 'b a)
(eval (b 1)) ;=> (apple a "red" "large")


In FOOP, I'm pretty sure we don't need a self special variable. A method takes the object as the first argument (usually), so this is what we use instead of self:


(define (Point:Point x y) (list Point x y))
(define (Point:distance p o) (sqrt (add (pow (sub (o 1) (p 1)) 2) (pow (sub (o 2) (p 2)) 2))))
(:distance (Point 10 20) (Point 30 40)) ;=> 28.28427125


The distance method takes two arguments: p and o. The first argument p is used like self would be in other languages. I could even make it more obvious (and Python-like) if I defined the method like so:


(define (Point:distance self other)
   (sqrt (add (pow (sub (other 1) (self 1)) 2) (pow (sub (other 2) (self 2)) 2)))
)


If what you actually wanted was a constructor that dynamically fills in the type, you could do this:


(define (Point:Point x y) (list Point x y))
(define (Shape:Shape center) (list (context) center))
(new Shape 'Circle)
(new Shape 'Rectangle)
(Circle (Point 43 23)) ;=> (Circle (Point 43 23))
(Rectangle (Point 55 33)) ;=> (Rectangle (Point 55 33))


Hope that helps :-)



m i c h a e l

newdep

#8
..that cleared it up.. I tried the (context) = self  befor but that did not work

I probably made a mistake then.. nice example thanks.
-- (define? (Cornflakes))

newBert

#9
FOOP is really an interesting and original manner to consider OOP. It reminds me of Elica NOOP (Natural OOP or "Easy" OOP) ...



I always had trouble managing this 'self' (or 'this') in Python or in other languages using '"classical" OOP. With FOOP, I think it's an unnecessary shortcut which risks  making the things confused.



It's just a personal point of view ;)
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>

m i c h a e l

#10
Quote from: "newBert"It reminds me of Elica NOOP (Natural OOP or "Easy" OOP)


The similarities are completely intentional :-)



What immediately grabbed me when I read Pavel Boytchev's two Elica papers (the ones you mentioned in the "More about Lutz's new macro" thread) is how Pavel wanted Elica to fit naturally within LOGO. Natural in this case means leaving the host language alone. This has influenced my newLISP explorations of FOOP.



m i c h a e l

newBert

#11
Quote from: "m i c h a e l"
 This has influenced my newLISP explorations of FOOP.


Well done and

thanks for this brainwave !

:)
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>