translation challenge from PythonTranslator...
Evil grin. OK, what about the following Scheme code.
Scheme
;;; Pointers in Scheme ;;; Adding pointer arithmetic is left as an exercise to the reader (define (make-pointer getter setter) (cons getter setter)) (define (pointer-ref ptr) ((car ptr))) (define (pointer-set! ptr value) ((cdr ptr) value)) (define-syntax address (syntax-rules () ((address var) (make-pointer (lambda () var) (lambda (value) (set! var value)))))) ;;; A few examples (define x 1) (define px (address x)) (display (pointer-ref px))(newline) (pointer-set! px 2) (display (pointer-ref px))(newline)Python
# Take a first cut. class Pointer: def __init__(self, var): self.var = var def set(self, val): self.var = val def get(self): return self.var x = 1 px = Pointer(x) print px.get() px.set(2) print px.get() # So far so good. But then this breaks... y = 10 py = Pointer(y) py.set(20) print y # When we print y, it's still 10. The problem is, # primitive types pass by value in Python. # So let's try making an Integer object. class Integer: def __init__(self, val): self.val = val def set(self, val): self.val = val def get(self): return self.val # And we can add a level of indirection. class Ptr: def __init__(self, var): self.var = var def set(self, val): self.var.set(val) def get(self): return self.var.get() print 'Test #2' y = Integer(10) print y.get() py = Ptr(y) py.set(20) print y.get() # And that seems to work.-- SteveHowell
So pointer allows you to call get/set on anything that already has a get/set method? So what's the point? :-)
Yep, it's kind of pointless to implement a pointer scheme in a language like Python, which solves problems just fine without them. That's what made this particular challenge so sinister. Insidious, even. -- SteveHowell
Nevertheless, it is an interesting problem. I explore a RubyLanguage version on the SinisterSchemeSampleInRuby page. -- JimWeirich
For the interested, here is some background information on the original Scheme code. The method outlined here to simulate pointers in Scheme was used in an early C-to-Lisp compiler for the MIT Lisp machine. (The C compiler on the later commercial Lisp machine didn't use this trick; it generated machine-code for the Lisp machine directly, just like a conventional C compiler.) One can have more operations that just set and get; in particular, one can implement pointer arithmetic. For this, the limitation in the ANSI C standard that pointer arithmetic only works on pointers that point into the same array is essential.
The piece of memory that contains the value of a variable is called a location in Scheme. In effect, the above Scheme code makes locations available as first-class values. We call this process reification. Thus, the Scheme code implements reifiable locations, or locatives for short. Note that these locatives have unlimited extent, unlike C pointers, which have dynamic extent.
There was a Scheme dialect called T that made heavy use of locatives.
So now you know why C "pointers" should really by called "first-class reified locations with dynamic extent." ;-)
I think I might know how to do arithmetic.
(def *heap* nil) (define (malloc () (def lexvar nil) (let (a (address lexvar) (set! *heap* (cons a *heap*)) a)))Then do heap manipulations. Can someone help with this?
...Oh, wait. I see...
(define (malloc (size) (if (= size 0) nil (cons nil (malloc (- size 1)))))) (define (ptr+ (aConsCell num) (if (= num 0) aConsCell (ptr+ (cdr aConsCell) (- num 1)))))