Subject: Re: please review my new *working* code - now with 20% more oop!
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 25 Feb 2009 04:31:43 -0600
Newsgroups: comp.lang.lisp
Message-ID: <x4OdnQQEnLSSgzjUnZ2dnUVZ_hGWnZ2d@speakeasy.net>
Pascal J. Bourguignon <pjb@informatimago.com> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) writes:
| > Secondly [and somewhat contrary to the above], I personally think
| > there's nothing wrong with doing a little fast prototyping with global
| > variables, *if* instead of DEFVAR (with earmuffs on the variables)
| > one uses DEFLEX[1] (with no earmuffs) for those sorts of developmental
| > convenience globals. One particular advantage, which I didn't discover
| > until after I'd been using DEFLEX for a while, is that once you've
| > figured out what you're doing they're *really* easy to fold into a LET*,
| > without having to do any massive renaming to get rid of the earmuffs.
| 
| Well I agree, but I'd say even more. 
| 
| LET is perfectly good to define "global" variables.
| That is, we don't really need global variables, what we need are
| variables at the REPL.
+---------------

That's what DEFLEX gives you, "variables at the REPL" that can
be safely rebound lexically without confusion.

+---------------
| Since we are using emacs with which we can easily edit any character
| anywhere in an emacs frame...
+---------------

[Note: *You* may be using Emacs; I'm not.]

+---------------
| ...there's nothing preventing us to edit exploratory code inside
| the REPL, and to use LET for REPL variables:
| 
| (let ((a (list 1 2 3 4)))
|    (remove-if (function evenp) a))
+---------------

This problem with this example is that it's way too simplistic.
Suppose the real task you're doing is something like this:

    (let* ((a (some-really-*long*-computation))  ; takes ~20 min to run
	   (b (we-do-not-really-know-yet-what-we-want-to-do-here a)))
      b)

then [IMHO] it's far better to do:

    (deflex a (some-really-*long*-computation))

and then noodle around figuring out what you want to do with the
values in A. You may decide you only want to do some of the
processing in the next step, so first you add that:

    (deflex b (we-do-this-much-at-least a))

and now we have B available to poke around at. We can even back up
and change part of the processing without having to recompute A:

    (deflex b (a-slightly-different-algorithm a))

But then, when it's *all* working correctly, sweep it into a single
LET* in inside a DEFUN:

    (defun foo ()
      (let* ((a (some-really-*long*-computation))
	     (b (a-slightly-different-algorithm a))
	     (c (the-rest-of-the-processing b)))
	c))

But I see no reason to sit there staring at an idle screen for 20
minutes at a shot each time I change something during development.


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607