Pass-by-reference : Could a C#-like approach work in Python?

Paul Foley see at below.invalid
Thu Sep 11 22:05:55 EDT 2003


On Fri, 12 Sep 2003 00:32:03 +0100, Stephen Horne wrote:

> On Thu, 11 Sep 2003 16:44:28 -0400, "Terry Reedy" <tjreedy at udel.edu>
> wrote:

>> My main objection was/is that expressed by Michael Chermside today:
>> this would complexify a simplicity that I consider a good feature of
>> Python.  Reading Bengt Richter's lastest response, also today, I
>> realize that 'ref x' would have to have much the same effect of Lisp's
>> FEXPR defun keyword -- of automatically quoting rather than evaluating
>> args -- although on just one rather than all.  Perhaps you should be
>> accused of 'trying to Lispify Python' -- or perhaps not ;-).

> I didn't know Lisp could do that. I really have to read up on Common
> Lisp one of these days.

Terry said "FEXPR", which tells you he's about 30 years out of date
wrt Lisp :-)  Any vaguely modern Lisp has macros instead of FEXPRs.



It's not difficult to implement what you're asking for in Lisp:

  (shadow 'defun)

  (defmacro defun (name lambda-list &body body)
    (let ((args '()) (mlet '()))
      (dolist (arg lambda-list)
        (if (and (consp arg) (eql (first arg) 'ref))
          (let ((tmp (gensym)))
            (push tmp args)
            (push `(,(second arg) (deref ,tmp)) mlet))
          (push arg args)))
      `(cl:defun ,name ,(nreverse args)
         (symbol-macrolet ,mlet
           , at body))))

  (defstruct (reference (:constructor %make-reference (reader writer))
                        (:conc-name ref%))
    (reader #'identity :type function)
    (writer #'identity :type function))

  (defmacro ref (obj)
    (multiple-value-bind (vars vals args writer reader)
        (get-setf-expansion obj)
      `(let ,(mapcar #'list vars vals)
         (%make-reference (lambda () ,reader) (lambda ,args ,writer)))))

  (defun deref (x) (funcall (ref%reader x)))
  (defun (setf deref) (v x) (funcall (ref%writer x) v))


E.g.,

USER> (defun foo (x (ref y) z (ref w))
  (setq y (+ x y))
  (setq w (+ y z w)))
FOO
USER> (let ((x 2) (y 4)) (values (foo 1 (ref x) 3 (ref y)) x y))
10   ; value returned by foo
3    ; value of x after call
10   ; value of y after call

[In fact, you can now use REF to make references to any "place", not
just simple variables: a particular element of an array, an instance
slot accessor, etc., etc.]

-- 
...Please don't assume Lisp is only useful for Animation and Graphics,
AI, Bioinformatics, B2B and E-Commerce, Data Mining, EDA/Semiconductor
applications, Expert Systems, Finance, Intelligent Agents, Knowledge
Management, Mechanical CAD, Modeling and Simulation, Natural Language,
Optimization, Research, Risk Analysis, Scheduling, Telecom, and Web
Authoring just because these are the only things they happened to
list.                                                      -- Kent Pitman

(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))




More information about the Python-list mailing list