Quote from: Jeff post_id=13069 time=1212583186 user_id=354
Previously, if I wanted to write in an object-oriented style:
(context 'Point)Code Select
(setq x 0 y 0) ; default slot values
(define (print-point)
(println (format "(%d, %d)" x y)))
(context MAIN)
(new Point 'my-point)
(setq my-point:x 4 my-point:y 12)
(my-point:print-point) ; => prints "(4, 12)"
Now, if something changed in the context Point, it would not change in my-point. This is prototype-based OO, just as in Javascript.
No, an 'object' defined in such a way is not a prototype-based OO at all. That my-point 'object' has not a refererence to its class neither its prototype, not only it is not a prototyped object but it is not even an object, by definition an object knows the class it belongs to and this object doesn't know so it's not an object, in prototype-based OO there's no class, everyting is an object and you create a new object from another object as prototype, so the new created object has a reference to its prototype, the object used as model for creation, this my-point 'object' has no reference to its prototype so it is not a protoype-based object. The only reason to call it an object is by the fact it's a data structure that holds data and behaviour.
By contrast, a FOOP object is a real object since it has a reference to its class and encapsulates data and behaviour.
Quote from: Jeff post_id=13069 time=1212583186 user_id=354
Therefore, if I wanted to implement a counter using a closure, I could do so like this:
(context 'Counter)Code Select
(define (Counter:Counter ctx (start-from 0))
(new (context) ctx)
(setq ctx (eval ctx))
(setq ctx:current start-from))
(define (increment (n 1)) (inc 'current n))
(define (decrement (n 1)) (dec 'current n))
(context MAIN)
(Counter 'counter 100)
(counter:increment 10)
(counter:increment 12)
(println counter:current) ; => 122
with this code you are using a context to represent an object, that's ok, the problem is you are pretending the object is also an instance of a class, and that's not the case, you are using context to represent both classes and objects, an pretending Counter is a (class) constructor for instance objects of that class, which is not. With
Code Select
(Counter 'counter 100)
you're pretending to create a new instance counter of class Counter , both (class and instance) represented as contexts.
Pretending this means instance counter knows about its class, Counter, but this is not the case because context counter is a copy of context Counter (thus including all its symbols, same data and functions) but have no reference to Counter context and no idea about a Counter (i.e. a symbol with its class name).
In other ways, let's suppose we have a function returning the class name:
Code Select
(define (classname) (context))
this function works for the class: (Counter:classname) => Counter but not for the instance (counter:classname) => counter when it should return Counter as well, and there's no way to write a function in the instance (context counter) that returns its classname because it has no way to know what class it was copied from
Quote from: Jeff post_id=13069 time=1212583186 user_id=354
I'm not confusing classes and instances :).
yes I think you are ;-)
Anyway as you sure know, if you want to get a closure you don't need all that structure, simply use the context as is:
Code Select
(context 'Counter)
(define (start (n 0)) (set 'current n))
(define (increment (n 1)) (inc current n))
(define (decrement (n 1)) (dec current n))
(context MAIN)
(Counter:start 100)
(Counter:increment 10)
(Counter:increment 12)
(println Counter:current) ; => 122