I apologize if this is a bit of a newbie question but I was curious about the capabilities of the Smalltalk language and how close it might be to something like LISP/Scheme. Is it possible within the Smalltalk language to write code which generates code. Is it possible for example to generate a completely arbitrary object at runtime?
>>>>> "Carter" == Carter <carterch...@gmail.com> writes:
Carter> I apologize if this is a bit of a newbie question but I was curious Carter> about the capabilities of the Smalltalk language and how close it Carter> might be to something like LISP/Scheme. Is it possible within the Carter> Smalltalk language to write code which generates code. Is it possible Carter> for example to generate a completely arbitrary object at runtime?
Yes, probably easier than most languages, in fact. The classic ST80 image, which is still living inside Squeak (www.squeak.org) has the entire compiler written in Smalltalk.
You can even create anonymous classes and give them behavior, then instantiate them. For example:
So, yeah. metaprogramming is definitely Smalltalk's playground.
Just another Smalltalk hacker, -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/> Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
> So, yeah. metaprogramming is definitely Smalltalk's playground.
Although one must admit that in Lisp, you would generate code by manipulating list structures, while in Smalltalk, you manipulate strings to generate source code. So Lisp has a very natural and direct way of dealing with program structures. If more involved symbolic manipulation of Smalltalk methods is needed, the Refactoring Browser with its parse nodes and transformations is the tool of choice.
> If more involved symbolic manipulation of Smalltalk methods is needed, > the Refactoring Browser with its parse nodes and transformations is > the tool of choice.
Its a good point - and the parse node support is all there as well - however as programmers I think its possibly easier to thing of lines of code. But if you want to get grungy I have examples like the following:
patch: aClass selector: aSelectorSymbol prepending: aStringNewStatement identifiedBy: aSymbol "Append a statement to the end of a method, or just before the last return (^) if one exists"
Carter schrieb: > I apologize if this is a bit of a newbie question but I was curious > about the capabilities of the Smalltalk language and how close it > might be to something like LISP/Scheme. Is it possible within the > Smalltalk language to write code which generates code. Is it possible > for example to generate a completely arbitrary object at runtime?
You already received some very technical info about how code is generated at runtime but since you are new to smalltalk here the info that is most interesting for you: First get Squeak from squeak.org to try the following examples.
In Smalltalk everything is an object, even classes. Everything can be looked at and manipulated at runtime. For example in a workspace write the following in a fresh line: Morph new explore. and then do-it by pressing alt-d. you have an explorer on the new Morph object. you can manipulate it at runtime: write in the textpane of the explorer: self color: Color red. then do-it by pressing alt-d. Adding dynamic behavior: again in the text-pane of the explorer self on: #mouseUp send: #value to: [self color: Color random]. you have added behavior to your already-in-existence-object.
"generating code at runtime" is very easy. The Funny thing is e.g. in squeak you are always(!) doing exactly that, when writing code (a method or a block(lambda)) you are in fact inside a running smalltalk program, the squeak-image. All Behavior you want an object to have is defined in its class (and superclasses), so if you want to add behavior(code) you can use a class-browser BUT if you e.g. really want to as you put it "write code which generates code" you can do the following: write a class-name, write compile:, then write a string like so: (in any text-panel, then do-it) Object compile: 'sayHi Speaker man say: ''hi'' '. You have just created a method sayHi that makes all objects able to respond to a message sayHi. e.g. try: 1 sayHi The number one just said hi through your speakers. This was the specific example of how you translate (at runtime) a string into code for dynamic behavior of objects. You can change the String into whatever behavior you want.
> Carter schrieb: > > I apologize if this is a bit of a newbie question but I was curious > > about the capabilities of the Smalltalk language and how close it > > might be to something like LISP/Scheme. Is it possible within the > > Smalltalk language to write code which generates code. Is it possible > > for example to generate a completely arbitrary object at runtime?
> You already received some very technical info about how code is > generated at runtime but since you are new to smalltalk here the info > that is most interesting for you: > First get Squeak from squeak.org to try the following examples.
> In Smalltalk everything is an object, even classes. > Everything can be looked at and manipulated at runtime. > For example in a workspace write the following in a fresh line: > Morph new explore. > and then do-it by pressing alt-d. > you have an explorer on the new Morph object. > you can manipulate it at runtime: write in the textpane of the explorer: > self color: Color red. then do-it by pressing alt-d. > Adding dynamic behavior: again in the text-pane of the explorer > self on: #mouseUp send: #value to: [self color: Color random]. > you have added behavior to your already-in-existence-object.
> "generating code at runtime" is very easy. > The Funny thing is e.g. in squeak you are always(!) doing exactly that, > when writing code (a method or a block(lambda)) you are in fact inside a > running smalltalk program, the squeak-image. > All Behavior you want an object to have is defined in its class (and > superclasses), so if you want to add behavior(code) you can use a > class-browser BUT if you e.g. really want to as you put it "write code > which generates code" you can do the following: write a class-name, > write compile:, then write a string like so: (in any text-panel, then do-it) > Object compile: 'sayHi Speaker man say: ''hi'' '. > You have just created a method sayHi that makes all objects able to > respond to a message sayHi. e.g. try: > 1 sayHi > The number one just said hi through your speakers. > This was the specific example of how you translate (at runtime) a string > into code for dynamic behavior of objects. > You can change the String into whatever behavior you want.
> Greetings! Have Fun!
Is there any performance diffrence between 'generating code at runtime using #compile:' and using Macros in Lisp ?
On Apr 8, 11:42 am, Carter <carterch...@gmail.com> wrote:
> I apologize if this is a bit of a newbie question but I was curious > about the capabilities of the Smalltalk language and how close it > might be to something like LISP/Scheme. Is it possible within the > Smalltalk language to write code which generates code. Is it possible > for example to generate a completely arbitrary object at runtime?
> Thanks in advance,
One other possibility that has not been mentioned in the previous posts, relies not on the compiler and string or parse nodes manipulation, but on the reflection capabilities.
Starting from Randal's example, let us assume that now you want another anonymous class with the same behavior. Instead of repeating the code that invokes the compiler for it, you could do:
If you want, you can change the selector for the method in the new class to #theOtherAnswer.You can even be fancier and change what the method #theOtherAnswer returns (e.g. to 43).
Although the above example still uses the compiler to to provide the prototype method, I hope that by now it is obvious that we can get rid of it and create the compiled method directly from a sequence of bytes, instead of copying it from an existing one. This would also take care of any performance issue caused by invoking the compiler. Of course, this just moves the problem from source manipulation to bytecode manipulation, which is not necessarily preferable, but it shows another way of doing it
On Apr 8, 5:42 pm, Carter <carterch...@gmail.com> wrote:
> I apologize if this is a bit of a newbie question but I was curious > about the capabilities of the Smalltalk language and how close it > might be to something like LISP/Scheme. Is it possible within the > Smalltalk language to write code which generates code. Is it possible > for example to generate a completely arbitrary object at runtime?
> Thanks in advance,
It is even possible to set an object to be its own class, and hence get prototype-oriented instances running under Squeak.
oroboros := Class new. oroboros superclass: Class. oroboros methodDictionary: MethodDictionery new. oroboros setFormat: Class format. oroboros primitiveChangeClassTo: oroboros basicNew oroboros class = oroboros --> true
daredevil <hithac...@gmail.com> wrote: > Is there any performance diffrence between 'generating code at runtime > using #compile:' and using Macros in Lisp ?
These are different things. Macros in Lisp are evaluated/expanded at compile time, so they're not comparable to generating code at runtime. The #compile: mechanism is probably a bit more complex since the whole compiler machinery is involved, but the resultant code is executed with the same performance as any other code in the system (in fact, all other code has been compiled using exactly that mechanism...)
On Apr 13, 12:19 am, Hans-Martin Mosner <h...@heeg.de> wrote:
> daredevil <hithac...@gmail.com> wrote: > > Is there any performance diffrence between 'generating code at runtime > > using #compile:' and using Macros in Lisp ?
> These are different things. > Macros in Lisp are evaluated/expanded at compile time, so they're not > comparable to generating code at runtime. The #compile: mechanism is > probably a bit more complex since the whole compiler machinery is > involved, but the resultant code is executed with the same performance > as any other code in the system (in fact, all other code has been > compiled using exactly that mechanism...)