What does Python fix?

Jason Orendorff jason at jorendorff.com
Sat Jan 19 01:52:15 EST 2002


Francois Pinard wrote:
> I also include below a little Scheme example randomly taken from my older
> things, which uses enclosed functions.  Such things may surely all been
> written in Python, but probably not so compactly.  I'm not really seeking
> an argument or fight here, just sharing an intuition.

An enlightened attitude, to be sure.  I enjoy this sort of thing;
I've tried to translate the Scheme into roughly equivalent Python,
to see if it's really longer.  Take a look.

I've translated (warning) to a Python function that (the reader should
assume) throws an exception.


> (define (modify redo undo focuses)
>   (and pos-flag (warning (_"Read-only in positioning mode")))
>   (letrec ((redo-function (lambda () (redo) (cons undo-function focuses)))
>            (undo-function (lambda () (undo) (cons redo-function
focuses))))
>   (redo)
>   (set! redo-list '())
>   (set! undo-list (cons undo-function undo-list))))

def modify(redo, undo, focuses):
    if pos_flag:
        warning(_("Read-only in positioning mode"))

    def redo_function():
        redo()
        return undo_function, focuses
    def undo_function():
        undo()
        return redo_function, focuses

    redo()
    del redo_list[:]
    undo_list.append(undo_function)

[You could of course give this a more brick-like appearance:
    if pos_flag:  warning(_("Read-only in positioning mode"))
    def redo_function():  redo();  return undo_function, focuses
    def undo_function():  undo();  return redo_function, focuses
but while it's legal Python, most people wouldn't think to do it.]

>     (define (undo)
>       (and (null? undo-list) (warning (_"No more undo!")))
>       (let ((pair ((car undo-list))))
> 	(set! focus-list (cdr pair))
> 	(set! redo-list (cons (car pair) redo-list))
> 	(set! undo-list (cdr undo-list))))
>
>     (define (redo)
>       (and (null? redo-list) (warning (_"No more redo!")))
>       (let ((pair ((car redo-list))))
> 	(set! focus-list (cdr pair))
> 	(set! undo-list (cons (car pair) undo-list))
> 	(set! redo-list (cdr redo-list))))

def undo():
    if len(undo_list) == 0:
        warning(_("No more undo!"))
    redo_fn, focus_list[:] = undo_list.pop()()
    redo_list.append(redo_fn)

def redo():
    if len(redo_list) == 0:
        warning(_("No more redo!"))
    undo_fn, focus_list[:] = redo_list.pop()()
    undo_list.append(undo_fn)


>     (define (replace value focuses)
>       (let ((restore (car focuses)))
> 	(if (null? (cdr focuses))
> 	    (let ((point focuses))
> 	      (modify (lambda () (set-car! point value))
> 		      (lambda () (set-car! point restore))
> 		      focuses))
> 	    (let ((point (cadr focuses))
> 		  (pos (current-index)))
> 	      (modify (lambda () (c-set! point pos value))
> 		      (lambda () (c-set! point pos restore))
> 		      (cdr focuses))
> 	      (set-car! focuses value)))))

I admit this stumped me.  :-)  Perhaps with some more
context I could have figured it out.  The first branch
almost makes sense...

def replace(value, focuses):
    restore = focuses[0]
    if len(focuses) == 1:
        def redo():  focuses[0] = value
        def undo():  focuses[0] = restore
        modify(redo, undo, focuses)
    else:
        point = focuses[1]
        pos = current_index()
        def redo(): ???
        def undo(): ???
        modify(redo, undo, focuses[1:])
        focuses[0] = value

Draw whatever conclusions you like from this. :)

## Jason Orendorff    http://www.jorendorff.com/





More information about the Python-list mailing list