AW: [ann] AEditor 0.10, folding added

Rather than use editor magic, why not just define an “initializer” function
on Class?

class Class
def initializer (attributes, externalized_attributes)
module_eval <<-END
# here generate code such as
# attr_accessor …
# attr_reader …
# def initialize …
# etc.
END
end
end

class A
initializer ([:x, :y, :z], [:x, :y])
end

That way the visible and maintained code for class A remains uncluttered and
declarative. The way the code generator “implements” the initializer
construct can change without impacting class A’s definition. If you really
wanted to, def initializer could even display your dialog e.g. if the
‘externalized_attributes’ argument was missing, but that seems like
inappropriate mixing.

Refactorings basically change some detailed code structure while preserving
some abstract properties (relatively speaking). I thought at first that you
were suggesting something like this as a way to write relatively abstract
Ruby that was less sensitive to refactorings.

Cheers …

···

“Richard Kilmer” rich@infoether.com wrote

That is powerful…but not what I am talking about.

Here is a simple example:

class Foo
def intialize(x,y,z)

at this point I press a magic generator key and this code appears:

 @x = x
 @y = y
 @z = z

and then displays a dialog to chose which of these you want

externalized

(if any) and inserts (above def initialize…) something like…

attr_accessor :x,:y
attr_reader :z

There’s a tradeoff here that fascinates me: on the one hand, code
generation of that sort definitely makes the code more “declarative”
in that the intent is more directly obvious to a human reader
(“explicit programming”). On the other hand, it makes the code much
more opaque to automated tools, because they can’t (statically) know
what the resulting code will be: the refactoring browser becomes
useless. In that sense, code generation leads to much less
declarative code: the only way you can know what your program is (much
less what it does), is to run it.

I believe that the only way Ruby will ever be able to have the same
level of tool support (of any kind, whether we’re talking about code
browsers, refactoring tools, or version control systems) that
Smalltalk does is by making the same sacrifice that Smalltalk did: to
completely avoid any form of code generation or macros. It’s not an
easy sacrifice to make - as someone used to Lisp, I found it very hard
to come to terms with - but as long as the language is dynamic enough
in other ways, I’m beginning to think it’s worth making. I’d be
curious to see what “declarative Ruby” (ie, Ruby consisting solely of
class and method definitions) would look like, and what new kinds of
tools would emerge if everyone started writing Ruby that way.

Avi

···

“Its Me” itsme213@hotmail.com wrote:

That way the visible and maintained code for class A remains uncluttered and
declarative. The way the code generator “implements” the initializer
construct can change without impacting class A’s definition.

That’s fascinating: you’ve just clarified for me why I’ve always found
it difficult to stick with Smalltalk. I’ve tried and tried, and yet
it’s always left me feeling flat. The thing for me is that I never
really found the tradeoff (environment power vs. language power) to
work too well for me.

So, I’m guessing that this could well be another of those cat
people/dog people kind of things. Some folks would rather have great
tools and will sacrifice some language power, while others will
sacrifice the tools for a language which is more expressive.

This is very interesting. Thanks, Avi.

Dave

···

On Thursday, August 14, 2003, at 09:51 PM, Avi Bryant wrote:

I believe that the only way Ruby will ever be able to have the same
level of tool support (of any kind, whether we’re talking about code
browsers, refactoring tools, or version control systems) that
Smalltalk does is by making the same sacrifice that Smalltalk did: to
completely avoid any form of code generation or macros.

I don’t think that this is normally a conscious choice. Having come
from 10+ years of Smalltalk, I find that things like dynamic generation
of code never even enter my mind when searching for a solution to a
problem. Personally, I fail to even see a need for such a thing. It
simply ties my mind in knots. I would be perfectly content if such
features did not exist. I wouldn’t argue for their removal, but am
rather expressing the idea that my mind simply doesn’t work that way.
Are there really problems that cannot be solved without dynamic code
generation?

···

On Fri, 15 Aug 2003 12:15:43 +0900 Dave Thomas Dave@PragProg.com wrote:

On Thursday, August 14, 2003, at 09:51 PM, Avi Bryant wrote:

I believe that the only way Ruby will ever be able to have the same
level of tool support (of any kind, whether we’re talking about code
browsers, refactoring tools, or version control systems) that
Smalltalk does is by making the same sacrifice that Smalltalk did:
to completely avoid any form of code generation or macros.

That’s fascinating: you’ve just clarified for me why I’ve always found

it difficult to stick with Smalltalk. I’ve tried and tried, and yet
it’s always left me feeling flat. The thing for me is that I never
really found the tradeoff (environment power vs. language power) to
work too well for me.

So, I’m guessing that this could well be another of those cat
people/dog people kind of things. Some folks would rather have great
tools and will sacrifice some language power, while others will
sacrifice the tools for a language which is more expressive.

“Dave Thomas” Dave@pragprog.com wrote.

I believe that the only way Ruby will ever be able to have the same
level of tool support (of any kind, whether we’re talking about code
browsers, refactoring tools, or version control systems) that
Smalltalk does is by making the same sacrifice that Smalltalk did: to
completely avoid any form of code generation or macros.

That’s fascinating: you’ve just clarified for me why I’ve always found
it difficult to stick with Smalltalk. I’ve tried and tried, and yet
it’s always left me feeling flat. The thing for me is that I never
really found the tradeoff (environment power vs. language power) to
work too well for me.

I am not convinced that there is a deep tradeoff of environment Vs. language
expressiveness and dynamism. The Lisp world back in the 80’s had a
combination of superb environment (easily comparable to Smalltalk) and heavy
use of arbitrarily sophisticated code generation (Lisp macros). All parts of
the environment, including the debugger, were amazingly macro aware.

Ok, maybe it did take a $40K piece of dedicated hardware to run, but chalk
that up to plan dumb market strategy on the part of companies like
Symbolics.

Is the particular style of code generation used in Ruby more difficult? Is
environment support hard because the Ruby abstract syntax tree is
inaccessible, and code generation done by string manipulation and evals?
Personally I think the lack of an accessible AST (admittedly somewhat more
work that in Lisp) is a pretty big obstacle to tools.

···

On Thursday, August 14, 2003, at 09:51 PM, Avi Bryant wrote:

It’s dangerous to say things like “a language which is more
expressive”. There’s nothing that would stop you from writing
Smalltalk with a Ruby accent, and use identical code generation
techniques. Early in learning Smalltalk, I did exactly this; in fact,
I wrote a very nice framework to support it. It was called MetaMonkey
(http://minnow.cc.gatech.edu/squeak/metamonkey), and let you add
code-generating class methods modelled after :attr_accessor. Being in
Smalltalk, I made sure it was nicely integrated with the environment -
the second you changed any of these code generators, or added new
calls to them, the browser would immediately update with the newly
generated code (in a special category so you could ignore it if you
wanted - this also made it easy to automatically clear and regenerate
everything at once).

Culturally, however, this didn’t fly. It’s not like I got any
lectures on the evils of code generation, people just didn’t use it.
There were always more elegant solutions to the problem. I posted an
example showing how to use MetaMonkey to simulate Ruby-style mixins,
but someone else posted code that added them for real. As a library.
Without changing the VM.

As I got better at implementing these more dynamic, more elegant
solutions myself, I stopped using MetaMonkey too. I also stopped
building specialized Compiler subclasses for use by my code, another
good way to confuse the tools. Technically, nothing was stopping me -
on a class by class basis, I could have made the choice to lose some
tool support and cultural compatibility, in return for the particular
sort of expressiveness that code generation gives, and yet I
consistently (these days) choose the Smalltalk Way.

So, yes, it’s a dog people/cat people thing. But it’s a complex
cultural issue, not a simple technical one. Which, to me, makes it
all the more fascinating. To me, the central paradox (and power) of
Smalltalk is that it:

a) technically encouranges you to change the language in any way you
want, at whichever level you want (see my note about subclassing
Compiler).
b) culturally encourages you not to, 999 times out of 1000.

Of course, that thousandth time is crucial - like when I needed to add
callcc. But it didn’t require generating any code to do so.

Cheers,
Avi

···

Dave Thomas Dave@pragprog.com wrote:

So, I’m guessing that this could well be another of those cat
people/dog people kind of things. Some folks would rather have great
tools and will sacrifice some language power, while others will
sacrifice the tools for a language which is more expressive.

“Its Me” itsme213@hotmail.com wrote in message news:d18%a.190441$xg5.136669@twister.austin.rr.com

I am not convinced that there is a deep tradeoff of environment Vs. language
expressiveness and dynamism. The Lisp world back in the 80’s had a
combination of superb environment (easily comparable to Smalltalk) and heavy
use of arbitrarily sophisticated code generation (Lisp macros). All parts of
the environment, including the debugger, were amazingly macro aware.

This is drifing off topic, but I’d like to know more. Was the LispM
environment truly comparable to (modern) Smalltalk? Current Lisp
environments (I’ve used Allegro and LispWorks) really don’t come
close, especially when it comes to tools like version control - what’s
the Lisp equivalent of ENVY or StORE? Or, since that’s where this
thread started, of the Refactoring Browser?

I’m not trying to get into a pissing match here - Lisp is wonderful,
and there are lots of things in CL (and in Scheme, and in Ruby for
that matter) that I miss in Smalltalk. But I honestly do think that
Smalltalk hits a sweet spot in terms of tool support, and I have a
hard time imagining how certain tools would work in the Lisp world -
like versioning by semantic chunks instead of raw text/s-exprs. If
those problems were in fact solved back in the 80s, I’d love to hear
about it.

avi@beta4.com (Avi Bryant) wrote in message news:6e869a6b.0308161015.3827ae54@posting.google.com

“Its Me” itsme213@hotmail.com wrote in message news:d18%a.190441$xg5.136669@twister.austin.rr.com

I am not convinced that there is a deep tradeoff of environment Vs. language
expressiveness and dynamism. The Lisp world back in the 80’s had a
combination of superb environment (easily comparable to Smalltalk) and heavy
use of arbitrarily sophisticated code generation (Lisp macros). All parts of
the environment, including the debugger, were amazingly macro aware.

This is drifing off topic, but I’d like to know more. Was the LispM
environment truly comparable to (modern) Smalltalk?

No it was very different.

Current Lisp
environments (I’ve used Allegro and LispWorks) really don’t come
close, especially when it comes to tools like version control - what’s
the Lisp equivalent of ENVY or StORE?

The Symbolics Lisp Machine had a source construction tool (SCT)
with versions and patch support and there was a versioning system
for source (VC).

Or, since that’s where this
thread started, of the Refactoring Browser?

There was some refactoring stuff in Zmacs. But not that much.

I’m not trying to get into a pissing match here - Lisp is wonderful,
and there are lots of things in CL (and in Scheme, and in Ruby for
that matter) that I miss in Smalltalk. But I honestly do think that
Smalltalk hits a sweet spot in terms of tool support, and I have a
hard time imagining how certain tools would work in the Lisp world -
like versioning by semantic chunks instead of raw text/s-exprs. If
those problems were in fact solved back in the 80s, I’d love to hear
about it.

Well, in terms of features the Lisp Machines will be good for
some surprises. It might be educational to read a bit about
InterLisp D from Xerox and/or Genera from Symbolics.
Here is a Quicktime movie with some audio comment,
demoing some of Genera - actually really only a tiny bit:
http://lispm.dyndns.org:8000/mov/lispm-2.mov or
http://lispm.dyndns.org:8000/mov/lispm-2a.mov

“Avi Bryant” avi@beta4.com wrote in message

I am not convinced that there is a deep tradeoff of environment Vs.
language
expressiveness and dynamism. The Lisp world back in the 80’s had a
combination of superb environment (easily comparable to Smalltalk) and
heavy
use of arbitrarily sophisticated code generation (Lisp macros). All
parts of
the environment, including the debugger, were amazingly macro aware.

This is drifing off topic, but I’d like to know more. Was the LispM
environment truly comparable to (modern) Smalltalk? Current Lisp
environments (I’ve used Allegro and LispWorks) really don’t come
close, especially when it comes to tools like version control - what’s
the Lisp equivalent of ENVY or StORE? Or, since that’s where this
thread started, of the Refactoring Browser?

I’m not trying to get into a pissing match here - Lisp is wonderful,
and there are lots of things in CL (and in Scheme, and in Ruby for
that matter) that I miss in Smalltalk. But I honestly do think that
Smalltalk hits a sweet spot in terms of tool support, and I have a
hard time imagining how certain tools would work in the Lisp world -
like versioning by semantic chunks instead of raw text/s-exprs. If
those problems were in fact solved back in the 80s, I’d love to hear
about it.

Lisp is in my distant past but here is what I recall.

Imo the LispMachine environment was truly comparable to modern Smalltalk.
Not in the details, but in the consistency and integration of all tools
(compilers, editors, debuggers, code browsers, run-time object browsers,
documentation tools, interface-builders, build-tools, persistence managers,
cross-language integration (the C-interface was just coming on line)…).
When the big bet on Lisp hardware failed, the lisp machine’s successors lost
some of those things.

Lisp had much better semantic chunks than text/s-exprs: first class Packages
and Modules.

A package act as namespaces, and (use-package P) set up namespace import
relations between packages.

A module is a subsystem-like code unit loaded up (as a single atomic unit)
from some number of files. (require M) loads M. (eval-when …) gave control
over whether code chunks got executed when compiled, loaded, etc.

The object system was based on generic functions (first Flavors, then CLOS)
with behaviors not necessarily coupled to a class definition. Hence if class
C is defined in package P, you can add generic functions on class C in any
other package and module. Multi-methods took this client-side polymorphism
even further. In addition, the classes themselves can be redefined
dynamically. Readers and writers were macros (comparable to Ruby’s
attr_accessor). And this is without really getting into the meta-object
stuff.

I don’t recall anything directly comparable to Envy. But with
modules/packages, an open object system with generic functions and class
redefinition, and decent persistence for these, it was somewhat less needed.
You could do some of the things the ENVY’s applications / sub-applications
provide. I’d say it did a pretty good job (1983, mind you) on providing a
shared code and documentation repository, concurrent access, atomic loads
and unloads, software component hierarchy; and not as good on aiding the
software component lifecycle.

I don’t think refactoring browsers had been conceived of in 1983.

Hth …