I bought the book Smalltalk Companion, by Ted Bracht, to see if I can
pick up Smalltalk. I've programmed in Java for several years, and I think I have a decent grasp of OOP issues. My main interest in Smalltalk lies in its much vaunted rapid development and rapid prototyping capability, being able to do things like program in the debugger, take advantage of the refactoring browser, and exploit its reflections and meta-programming capabilities. Toward this end, I'm afraid I have not benefited much from the Smalltalk Companion. The book focuses on developing a single medium-size application in Smalltalk, trying to illustrate the properties of the language and the environment through the process. The MVP toolkit is introduced very early in the process, while other more salient Smalltalk language features are deferred until after the rudiments of MVP are covered. GUI programming is only one aspect of Smalltalk programming. The fact that the Smalltalk environment makes it nearly effortless in comparison to what Java programmers are forced to contend with illustrates the incredible power and flexibility of Smalltalk, but again it is only one aspect---an aspect which is orthogonal to the more language-oriented and development-oriented concepts (programming in debuuger, refactoring browser, meta-language programming) that I alluded to earlier. What I'm looking for is a Smalltalk tutorial that can get me up and running quickly. From the first 2 chapters of the Bracht book, I learned how to test code snippets in the Workspace by highlighting and evaluating them. I learned about the class hierarchy browser, and how to introduce a new class. Missing though are insights that I seek to translate the concepts that I learned in developing in the file-based language of Java with its edit/compile/test iterative development process to the image-based interactive development process of Smalltalk. Things I am still not sure of: 1) Java classes are stored in source files, so it is easy to cat or more the file to view its contents. Smalltalk classes are stored in an image (somewhere). Can I store a class in 2 different images? Can I experiment by storing different version of a class in separate images? Can I merge 2 different images into a single image or separate an image into sub-images? 2) Java organizes classes into packages. Dolphin Smalltalk also seems to have packages, but are they the same as Java packages? Java packages provide a namespace so that 2 Java classes with the same name can be kept in separate packages; do Smalltalk packages also provide a separate namespace? Java packages provide a tree-based hierachy corresponding to qualified class names (java.io.FileWriter); do Smalltalk packages provide the same? 3) Suppose I type some code snippet into the Workspace that I find useful, but am not yet prepared to transfer that portion of code into a class. How do I save that snippet? Do I just copy it and store it into a file, or is there a way to save it so that I can quit the Smalltalk envionemnt but still have the code available the next time I start it up? I suspect that these are silly and pedestrian questions, because I have not yet made the leap from file-based development to image-based development. However, the Bracht book does not seem to be helping me in this transition. Can someone point to a good resource for picking up these concepts? Pior to starting to learn Smalltalk, I was for a while dabbling in the scripting-language Ruby, which is also file-based. Ruby is quite a good language, with a nearly identical object model to that of Smalltalk, however if my goal is to develop rapidly, I think I am undercutting myself by not taking advantage of a more powerful development environment. For this reason, I'd like to pick up Smalltalk as soon as I can---the development environment as well as the language. Many Thanks, Damon |
"Damon" <[hidden email]> wrote in message
news:[hidden email]... > I have not benefited much from the Smalltalk Companion. You've only read two chapters, right? :) Personally, I love Bracht's approach. That's exactly what I want in a tutorial book--build an app, throwing in language stuff and development environment stuff along the way. A Dolphin-specific book especially helps, because it addresses the specific features of the IDE, which is one of the main reason people use a Smalltalk. But sure, Bracht's approach is not for everyone, I guess. I never learn a language from one book. I'm reading Bracht for MVP and Dolphin tips. I'm reading Kent Beck's "Smalltalk Best Practice Patterns" for general Smalltalk idioms (which don't address your questions). I'm combing the web (some good sites are mentioned on http://www.mwilden.com/smalltalk). But this ain't Java. You should find package management as simple or simpler than in Java, but what you won't find is 100 books at Borders telling you how to do it. The best teacher (as always) is experience. You could actually answer some of your questions yourself with some simple experiments (like saving a class in two images--think about Object). So play! Evaluate!! Inspect!!! Have fun!!!! But maybe this newbie (as of two weeks today) can save you some time. Bracht describes (at the end of chapter two) the basics of using packages for projects. If you set your packages to PAX format (it's a source control option), their classes will be saved out into multiple .cls text files, which you can then print, etc. But Smalltalk doesn't really believe in this. You'll find you don't often need to look at "the whole class." Yes, you can store a class in two images. An image is just a VC++ workspace, as far as I'm concerned, but more powerful. The package is your source--the image is just the environment.. Smalltalk has no namespaces. You have to go back to prefixes on global symbols. It turns out to be less annoying than I expected. Using a prefix has the benefit of bringing your classes together when listed alphabetically. But proper namespaces would be much better. Smalltalk code can be saved to any text file, usually ending with .st. Or you can just leave it in that workspace window (which is saved with the image) until you need it. Final words of advice: Don't try to pick up Smalltalk as fast as you can. :) I spent half a day over one paragraph in Bracht's book, till I felt I understood it. Then, last night, I did something in Smalltalk in a couple minutes that would've taken hours in C++. |
In reply to this post by Damon
"Damon" <[hidden email]> wrote in message
news:[hidden email]... Damon, > 1) Java classes are stored in source files, so it is easy to cat or > more the file to view its contents. Smalltalk classes are stored in > an image (somewhere). Can I store a class in 2 different images? Can > I experiment by storing different version of a class in separate > images? Can I merge 2 different images into a single image or > separate an image into sub-images? You need to get used to Class hierarchy browser (or system browser), since 99,9% of your code browsing will occur in it. It has advantage over file browsing because it reveals the structure of classes and hierarchy of them. Anyway sometimes it takes some time to adopt from file oriented approach. As for other questions, answers are mostly yes (except for image merge which is more complex to answer), but this if you are woried about this at this stage, you are probably on the wrong path :) . Stick to class browser, and put all your "play" classes into a "me-play" package. Also take look at the wiki for advices about maintainig an image. > 2) Java organizes classes into packages. Dolphin Smalltalk also > seems to have packages, but are they the same as Java packages? Java > packages provide a namespace so that 2 Java classes with the same name > can be kept in separate packages; do Smalltalk packages also provide > a separate namespace? Java packages provide a tree-based hierachy > corresponding to qualified class names (java.io.FileWriter); do > Smalltalk packages provide the same? Dophin packages do not provide name spaces. They are basically sets of classes, that can be loaded (or unloaded) into the image as whole in a one simple operation. So this is most common way how you share code between images, you put related classes into a package, save it, and later you can use it in another image, or to rebuild from the scratch one you are working at. Packages have some other roles, but they are at the begginig less important > 3) Suppose I type some code snippet into the Workspace that I find > useful, but am not yet prepared to transfer that portion of code into > a class. How do I save that snippet? Do I just copy it and store it > into a file, or is there a way to save it so that I can quit the > Smalltalk envionemnt but still have the code available the next time I > start it up? When you save the image contents of your workspace will be avalilable when you start your image again. In addition to that , you can save workspaces, so they end up in some file like my-workspace.st, and you can open this workspace in any image that you wish. But try not to overuse workspaces to the point where they becomme spageti like. Sooner you start playingwith CHB the better. rush -- http://www.templatetamer.com/ |
In reply to this post by Damon
Damon wrote:
> I bought the book Smalltalk Companion, by Ted Bracht, to see if I can > pick up Smalltalk. I've programmed in Java for several years, and I > think I have a decent grasp of OOP issues. > [...] > Missing though are insights that I seek to translate the concepts that > I learned in developing in the file-based language of Java with its > edit/compile/test iterative development process to the image-based > interactive development process of Smalltalk. Welcome aboard! I made the Great Leap Forward from Java to (Dolphin) Smalltalk a few years ago and I think I can still remember how it felt. My motives were not too unlike yours -- curiosity about what was claimed to be a better way of working, more than anything. What I got out of it wasn't quite what I'd expected. I was hoping to find better tools, what I found was a different way of thinking about OO. You've already had a couple of fairly direct answers to your specific questions. I'm going to try to take a step back and talk a little about the new way of thinking. I'll try to relate it to your questions as I witter on, but the connections may seem (be) rather indirect. BTW, this is all -- obviously -- only my own opinion. Other Smalltalkers might disagree with much, or even all, of what I want to say. The "image" is the *central* concept of Smalltalk. In comparison, nothing else is very important. (I'm aware that there are Smalltalk dialects that don't have images, but I -- personally -- can't see the point.). If you are like me, then you are currently thinking of a big difference between Smalltalk and Java being that Java stores code in files, whereas Smalltalk keeps it in the image. That's sort of true, and I'll get back to it, but, for a minute, just forget about code, it's not important (really!). What matters is *objects*. The image is the place where the objects live. Technically, the image is a garbage-collected heap that can be saved to file, and later restored, thus saving and resuming the state of a computation. *Technically* that's true, but it isn't at all a helpful way to think about it. A more organic metaphor works much better. I think of the image as a deep, murky, pond where objects move around in the depths like fish. It's an important part of the metaphor that the objects are *independent* of me. Even if I designed and wrote the classes, once an object has been created it has an independent existence. I can talk to it, I can ask it to perform operations, but it is separate from me. In a sense it is "my" object, but it is only "mine" in the same way that a pet, or a rose bush, or a table, could be "mine". The image is where the objects live. Not the code, the objects. We'll get back to the code in due course, but not yet. The Smalltalk environment is just a place where you can talk to objects; no more, no less. Oh, sure its got class browsers, debuggers, editors, etc, but that's all tinsel. What matters is that it is a place where you can interact with the objects. I'll get back to the "tinsel" later too, but for now, I want to talk about the one part of the environment that isn't just a productivity aid: the workspaces. Workspaces are the medium through which you talk to objects. You *can* describe workspaces as "containing snippets of code" which you execute, but IMO that's exactly the wrong way to think of it. A better picture (slightly tongue-in-cheek) is as a kind of singles bar, where you can meet objects, talk to them, check them out, get to know them. Each workspace has a number of objects that are (temporarily) living there; they are the values of the variables in the workspace. In most cases they'll die when you close the workspace, but until you do they'll survive and you can talk to them. I keep some workspaces hanging around for days if they contain objects that are important for what I'm doing. The way you "talk" is by sending messages written in the Smalltalk programming language, but that's almost incidental. The important thing is that you are communicating with them using an interactive text-based medium, like using an IRC channel. I very much like that picture. A workspace is like an IRC channel for talking to objects. One difference is that the other users of a real IRC channel don't usually die when you sign-off (at least I don't think so, I admit that I've never actually used IRC). (BTW, you can save the *text* of the workspace in a .ST file -- it's actually saved as RTF -- but that just saving a transcript of the conversation. If you re-opened the text in a different workspace window then you'd see the text but the objects wouldn't be behind it. Using cut-and-paste from one workspace to another has the same effect and can be a good way of killing unwanted objects without loosing the record of what was said.) Another way of interacting with objects is to use the Inspector(s). They give you a much more nuts-and-bolts, low-level, view of the object -- a more intimate view, if you like. I, personally, don't think that the Smalltalk world has yet woken up to what inspectors *could* be, but the current implementations (like "flipper" in Dolphin) do at least allow you to see inside the objects. An image will contain many objects, some long lived (living, perhaps, for decades), most very short lived indeed. Some will be simple or trivial, like Strings and Points. Others will have complicated internal structures, and/or complicated behaviour. But they are all objects, and they all live in the image, and you talk to them in workspaces. Classes are one particularly interesting kind of object. Remember I'm *still* not talking about code (that comes later), I'm talking about the objects called classes. Just like any other objects, you can invite them to join you in a workspace: class := String. and then you can use the magical Smalltalk object-oriented IRC to talk to them: class name. "--> #String" class allSubclasses size. "--> 3" and so on. So classes are objects, and they live in the image. Since Smalltalk is a programming environment with GUI features, there's nothing more natural once we've reached the point where we have an image full of objects, than to start writing tools that allow us to interact with the objects in more structured/convenient ways. Workspaces and Inspectors are fine for the basics, but we'll soon want better tools that allow us to see the relationships between objects (or some subset of objects -- the classes for instance), or what messages they understand. Maybe we'll want to be able to modify their behaviour, or create new kinds of objects. That's exactly what the IDE provides. The class browsers, etc, are merely a collection of tools for talking to objects. They are useful, even highly desirable, but ultimately dispensable because we could talk to the objects without them, anyway. But now it's time to get to the subject of code. The progression I've taken, starting at objects, then the important tools, then classes, then more tools, and finally code, really does represent a progression from the most important to the least. In this way of thinking the code is the least important part of programming in Smalltalk. (Of course, I'm schizoid about this, I don't *really* think that the code is the least important part -- just muck with my code's formatting and watch me explode -- but on the other hand, I really *do* think that the objects are more important.) Code is how we tell objects how to behave. It's text in the Smalltalk programming language. We're programmers so we care about code; when we wrote the tools for looking at objects, we naturally designed the tools so that we could also see the associated source code. For instance our special tool for looking at classes (the class hierarchy browser) allows us to see the source of the methods, to change the source and recompile, etc. That's natural for us as programmers. If we weren't programmers then we'd want different tools, and we'd be interested in talking to different objects. Such systems, built for non-programmers, are called "applications", but they are still just Smalltalk -- tools for talking to objects that live in an image. (A big difference is that the "image" of an application is typically not persistent, unlike the image of the IDE). Back to code. Granted that the most important thing is the objects and how they behave, we still do care about the code. We want to organise it, back it up, put it under source code control, etc. A class is an object that lives in the image, but the source code *for* that class is something else. For all sorts of reasons, we want to keep that outside the image. The way that Dolphin organises source-code is via Packages. A package is a collection of the source code for classes and methods (and a few other things too, which don't matter here) that is kept outside the image in one or more files. You can load the package into the image, which will create an actual Package object, and class objects corresponding to the source-code. Or you can "uninstall" the package, which really means killing the Package object and the Class objects. So a package is just a way of collecting related source-code together. Some Smalltalks go further and associate namespaces with packages. Dolphin doesn't (and I'm not at all sure that I think that's a bad thing). You can load the same package into different images, in which case you'll have duplicate versions of the class objects living in both images. If you do that then you'll want to be careful not to make changes to the classes in one image and not the other, because then the package file cannot reflect the state of both images. The package mechanism is relatively simple; it could be improved, but I find it adequate for my needs. Package files are text files, you can edit them with vi, or notepad, or whatever. Occasionally I do that if I want to make particularly sweeping changes to the source. Of course, if you do that then you have to install the changed version into the image before it'll do anything useful. Notice how very different this way of thinking is from the way that even the best Java IDEs encourage you to think. When I started out in Smalltalk I was thinking of the IDE as if it was a Java IDE. I though of it as a tool that allowed me to write code, and had features to allow me to browse and test the code. After a year or so I realised that I'd turned the picture upside down completely, and in the process had revised my conception of what Object-Oriented programming is all about. As a Java (or C++) programmer I had pretty much thought my .java (and .cpp) files *were* the classes, and I thought that creating classes was what programming was *about*. I now think of the objects as being the important thing, and the classes as very secondary, hardly more than an implementation detail. I *feel* that that has made me a better programmer. Of course it's not possible to know for sure, but if it has, then it all comes down to Smalltalk's workspaces... (A couple of asides for seasoned Smallalkers, if any are still reading: Was Dolphin the first Smalltalk to have workspaces that kept the values of variables rather than throwing them away after each evaluation ? VW used to discard them and I think VASt still does. Squeak keeps the values, but I don't know how long that's been true. Anyway, whichever implementation it was that introduced the idea can -- I think -- claim to be the first *truly* object-oriented Smalltalk. Presumably also the first truly object-oriented IDE of any kind. Writing this has made me focus on the unease that I still feel with programming-in-the-debugger. I was already a bit suspicious that it might encourage a (crypto-)topdown approach to decomposition. I'm now starting to wonder whether it also is part of a "code-centric" way of thinking, rather than the "object-centric" mindset that I think Smalltalk *should* foster.) BTW. One book on Smalltalk that I heartily recommend, especially if Ted Bracht's "teach-by-example" approach isn't right for you, is Chammond Liu's book, "Smalltalk Objects, and Design". It's the best book on Smalltalk that I've ever read (although it's not Dolphin-specific), and in fact I'd say it's the best book on OO that I've ever read too. Oh well. Once again, this has been a longer post than I'd intended. I don't know if anything I've said has made any sense to you, or has seemed even slightly relevant. I've had fun writing it anyway... -- chris |
"Chris Uppal" <[hidden email]> wrote in message
news:3e81ce94$0$59849$[hidden email]... > Damon wrote: > You've already had a couple of fairly direct answers to your specific > questions. I'm going to try to take a step back and talk a little about the new > way of thinking. I'll try to relate it to your questions as I witter on, but > the connections may seem (be) rather indirect. Chris, this is _very_ nice. It would also make a very valuable contribution to the wiki, probably showing that even if contributions are happen rarely, it is important that they are possible. rush -- http://www.templatetamer.com/ |
In reply to this post by Chris Uppal-3
Chris
A great post. You wrote in message news:3e81ce94$0$59849$[hidden email]... > ... > The "image" is the *central* concept of Smalltalk. In comparison, nothing else > is very important. (I'm aware that there are Smalltalk dialects that don't have > images, but I -- personally -- can't see the point.). If you are like me, then > you are currently thinking of a big difference between Smalltalk and Java being > that Java stores code in files, whereas Smalltalk keeps it in the image. That's > sort of true, and I'll get back to it, but, for a minute, just forget about > code, it's not important (really!). What matters is *objects*. >... Absolutely. Its surprising how many people don't get this, or don't agree with it, but for us it's absolutely key. > > The image is the place where the objects live. Technically, the image is a > garbage-collected heap that can be saved to file, and later restored, thus > saving and resuming the state of a computation. *Technically* that's true, but > it isn't at all a helpful way to think about it. A more organic metaphor works > much better. I think of the image as a deep, murky, pond where objects move > around in the depths like fish. ... At Smalltalk Solutions 2001 (I think) there was a panel on future directions for Smalltalk (again, I think), at which Andy gave his "Sea of Live Objects" speech, pointing out that the really great thing about Smalltalk was the fact that one "programmed" it by manipulating a live world of objects, rather than by writing source code in files and transitioning between distinct "programming" and "debug and test" states. We were trying to encourage people to build on this as a strength, but we came away thinking that it had not been that well received. >[great stuff snipped] > .... > (A couple of asides for seasoned Smallalkers, if any are still reading: > > Was Dolphin the first Smalltalk to have workspaces that kept the values of > variables rather than throwing them away after each evaluation ? >... We've always thought it was Digitalk Smalltalk. We "grew up" on that, and couldn't concieve of not having workspace variables, and I for one found it very difficult to work in a famouse Smalltalk that didn't have them at the time, especially since that Smalltalk also required one to select single line expressions before one could evaluate them. Aargh! >...snip... > > Writing this has made me focus on the unease that I still feel with > programming-in-the-debugger. I was already a bit suspicious that it might > encourage a (crypto-)topdown approach to decomposition. I'm now starting to > wonder whether it also is part of a "code-centric" way of thinking, rather than > the "object-centric" mindset that I think Smalltalk *should* foster.) >... Personally I think the opposite is true. Programming in the debugger is so powerful because of the immersion in the objects that make up the state of the program at the debug point. All that "context" is a local view of the sea of live objects that helps one understand what code needs to be written to support the desired behaviour in a much more concrete way than the traditional, more abstract, approach of writing the code as a separate activity from running it. In static, file-based languages, one tends to write code in large chunks, having to think quite hard about how it will behave when you run it, what the values of the arguments will be, etc. Then one runs and tests, does a bit of debugging (and a few minor code changes with "edit-and-continue", wow), but at some point one has to drop out of the live session to go back and write more code, refactor, etc. In Smalltalk one does this at a much finer level of granularity. One can write one method or expression and test it out directly. Even then there is still a distinction between the coding activity, and the debug/test activity. Once we start introducing programming in the debugger, we can eliminate this distinction in a number of important cases, and literally start fleshing out the code as we run/test it, either in the debugger itself or in other browsers while the session is still live. With automated refactorings we can easily tidy up later when the smell gets too strong to ignore, and at that point step back and view the code as an artifact in its own right that we want to exhibit all the usual software engineering attributes. Regards Blair |
"Blair McGlashan" <[hidden email]> wrote in message
news:b5ujue$2bqimr$[hidden email]... > In static, file-based languages, one tends to > write code in large chunks, having to think quite hard about how it will > behave when you run it, what the values of the arguments will be, etc. Right, because you have to model the computer in your head (as well as keeping your own logic straight). Predicting is much harder than simply observing. |
In reply to this post by Chris Uppal-3
"Chris Uppal" <[hidden email]> wrote in message news:<3e81ce94$0$59849$[hidden email]>...
> Damon wrote: > > > I bought the book Smalltalk Companion, by Ted Bracht, to see if I can > > pick up Smalltalk. I've programmed in Java for several years, and I > > think I have a decent grasp of OOP issues. > > [...] > > Missing though are insights that I seek to translate the concepts that > > I learned in developing in the file-based language of Java with its > > edit/compile/test iterative development process to the image-based > > interactive development process of Smalltalk. > > Welcome aboard! > > I made the Great Leap Forward from Java to (Dolphin) Smalltalk a few years ago > and I think I can still remember how it felt. My motives were not too unlike > yours -- curiosity about what was claimed to be a better way of working, more > than anything. What I got out of it wasn't quite what I'd expected. I was > hoping to find better tools, what I found was a different way of thinking about > OO. > Thank you for this great post about the "sea of objects" perspective regarding the Smalltalk image. Learning the process in which one thinks and develops against the image was my main goal in seeking tutorials and documentation. Your post has aided me towards that end. I actually had heard of the "sea of objects" explained earlier by one noted developer who argued that programming with "live objects" was a more natural process, as that is how we interact with the natural world. We do not leave the world to some alternate syntactic world (modify the code, recompile it, and re-execute it) when we interact with an object to produce a desired effect. > I'll get back to the "tinsel" later too, but for now, I want to talk about the > one part of the environment that isn't just a productivity aid: the workspaces. > Workspaces are the medium through which you talk to objects. You *can* describe > workspaces as "containing snippets of code" which you execute, but IMO that's > exactly the wrong way to think of it. Thanks. This last point has helped me clarify one important perspective about the workspace's role in interacting with the image. > > Back to code. Granted that the most important thing is the objects and how they > behave, we still do care about the code. We want to organise it, back it up, > put it under source code control, etc. A class is an object that lives in the > image, but the source code *for* that class is something else. For all sorts of > reasons, we want to keep that outside the image. The way that Dolphin organises > source-code is via Packages. A package is a collection of the source code for > classes and methods (and a few other things too, which don't matter here) that > is kept outside the image in one or more files. You can load the package into > the image, which will create an actual Package object, and class objects > corresponding to the source-code. Or you can "uninstall" the package, which > really means killing the Package object and the Class objects. Bingo! This is one of the main ideas that had eluded me. The differentiation between live objects in the image and static code in a package did not hit me until you phrased it in this manner. > Oh well. Once again, this has been a longer post than I'd intended. I don't > know if anything I've said has made any sense to you, or has seemed even > slightly relevant. I've had fun writing it anyway... > > -- chris And I appreciate it a great deal. It's been a highly rewarding read. Damon |
In reply to this post by rush
"rush" <[hidden email]> wrote in message news:<b5qcvm$8ed9$[hidden email]>...
> > When you save the image contents of your workspace will be avalilable when > you start your image again. In addition to that , you can save workspaces, > so they end up in some file like my-workspace.st, and you can open this > workspace in any image that you wish. But try not to overuse workspaces to > the point where they becomme spageti like. Sooner you start playingwith CHB > the better. > > rush Thanks for the explanations to my questions. To clarify one last point: Is the workspace part of the image as well, so that saving the image saves the contents of the worksapce? If so, is the workspace an object (a singleton object) in the image? Thanks, Damon |
Damon,
> point: Is the workspace part of the image as well, so that saving the > image saves the contents of the worksapce? Yes, though you might also want to periodically save the text to a separate .st file; that way, you can reload the text if you close the workspace in the image, or otherwise have an image meltdown. In that case, the separate file is merely a backup (not unlike a package for classes, view resources, etc.); your edits would affect only the copy in the image until you save the file. For example, if you change the text, save the image but NOT the file, then the image will reload with the changes to the text in the workspace, but the file will not contain them. Please ask questions if that's not clear. > If so, is the workspace an > object _Everything_ is an object :) The answer to your question is yes. > (a singleton object) in the image? However, it is not a singleton, but that's either what you want, or if it is a "problem" for you, there is a way to compensate for it. Is there something that you are trying to do that would be helped by a singleton workspace? If so, please describe it and we'll find a way to cope with the fact that workspaces are not singletons; put another way, while you could modify your image to make SmalltalkWorkspaceDocument a singleton, I don't recommend doing that. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Chris Uppal-3
"Chris Uppal" <[hidden email]> wrote in message news:<3e81ce94$0$59849$[hidden email]>...
This was such a great post, that I can't quite let it go. The ideas presented here have flicked on a switch so that I want to learn more details. > When I started out in Smalltalk I was > thinking of the IDE as if it was a Java IDE. I though of it as a tool that > allowed me to write code, and had features to allow me to browse and test the > code. After a year or so I realised that I'd turned the picture upside down > completely, and in the process had revised my conception of what > Object-Oriented programming is all about. As a Java (or C++) programmer I had > pretty much thought my .java (and .cpp) files *were* the classes, and I thought > that creating classes was what programming was *about*. I now think of the > objects as being the important thing, and the classes as very secondary, hardly > more than an implementation detail. This was my mindset when I was working through the Bracht book. It came across as presenting the Smalltalk environment as an IDE. Yet, I had heard of the "sea of live objects" concept that Blair alluded to, but I could not make that leap from thinking of programming as creating classes to programming as maintaining and interacting with objects in the image. I think another book, called "Squeak: A Quick Trip to ObjectLand" tries to present the image as an arena of objects, but that book was simply too "Lewis Carroll"-whimsical for my taste, emphasizing dialogs and metaphors over straightforward development techniques. Can we start from the very beginning once again to solidify my understanding? In the file-based Java approach, there is a stark contrast between classes and instances. Classes are represented lexically and syntactically in a file at compile-time. At run-time, the classes are instantiated as instances which then act as objects. We can also think of classes as objects, but the distinction lies in the fact that classes are static while state information is available in instances. Now let's transition to Smalltalk and image-based development. In Smalltalk, everything is an object, so classes and instances are unified as just objects, and the image offers persistance for all objects. Yet, the earlier distinction between classes offering behavior and instances storing state and identity still holds. When I type in the workspace: x := String new 'Hello world!'. String is a (class) object that lives in the image. The String object can be identified by name: it is called 'String'. The variable x, however, is not an object; it merely points to an (instance) object that was just created. That newly created String instance now lives in the image, but its identity is not explicit, as in the case of 'String'. Its identity is hidden; only the variable 'x' knows the identity of the instance. If x gets overwritten x := 5 that "Hello world!" instance loses its liveness, and is available for garbage collection. So is it right to say that both instance and class objects live in the image, but class objects are: 1) identified by explicit names 2) already alive when introduced into the image 3) and stay in the image indefinitely 4) but do not have state information while instance objects: 1) have hidden identities 2) have to first be instantiated to come alive (born and die in the image) 3) stay in the image as long as liveness is maintained via variable reference 4) hold state information in the image. To take things a little further do blocks live in the image? y := [Transcript show: x.] Ie, do they: 1) have hidden identities 2) already alive when introduced into the image 3) stay in the image as long as liveness is maintained via variable reference 4) hold state information in the image so that blocks are objects that have a mixture of class and instance properties? Finally constants (1,2,3,...) and literals ('hello world!') are: 1) identified by explicit names 2) do not have to be instantiated to become alive and do not have to be introduced into the image 3) stay in the image as long as liveness is maintained via variable reference 4) hold state information in the image Assuming that the above is right (please correct me if I'm off), I want to ask a question about the relationship between the workspace and the image. Suppose in the workspace, I type: z := 1 z := 2 and evaluate both statements. First, both constants become alive and are available in the image. After the 'z' variable is assigned '2', the '1' object may be garbage collected. However, suppose after evaluating these 2 statements, I then evaluate just the first statement. Then the 'z' variable is assigned the '1' object, which becomes alive again. Afterwards, I quit the smalltalk environment, restart it once again, and view the workspace. In Dolphin Smalltalk, the 'z' variable still maintains its last value of 1, so that the state of the workspace does not correspond to the actual layout of the code within the workspace. Perhaps this is much ado about nothing, but I was wondering whether the workspace should be an object in the image, and if the state of the workspace can be maintained as well. If so, then the workspace has the added complexity that its state does not correspond to the sequential layout of code it contains, as the order of evaluation of its code is non-deterministic. If anyone is still with me, after those musings, I'd like to ask a couple of final questions about the image and workspace. 1) I assume it's possible to start off with an empty image, and proceed from there by importing packages of code into the image to work with objects. Ie. Suppose I have only only 1 object called Main in the image with a single method called doit. Can someone show me how to write the Smalltalk code in the doit method to import a package and load a String object into the image in order to create a 'Hello world' string? Thus I would only have to evaluate Main doit. to start from a clean state in the image, and get have the application proceed from there. 2) I have up to now been using the workspace as a scratchpad to evaluate those "snippets of code" rather than as a means of communicating with objects in the image. Either way, is this the way things are usually done in Smalltalk? One proceeds by trying things out and experimenting in the workspace to see if a program can be put together from a bunch of object interactions. After a while if things start to work, to move the code from the workspace and into a method? Ie, does one first use the workspace as a playground, and then solidify the process by saving the code for the interactions into a method by cutting and pasting the text from the workspace into the CHB? 3) Finally, I hear a great deal about how powerful a refactoring browser is. What is a refactoring browser? I'd like to try one, but the version of sample Dolphin Smalltalk in the Bracht book does not contain a refactoring browser. In simple terms, tough, what does a refactoring browser do? Many thanks for the previous responses. My interest in Smalltalk has risen dramatically after reading through these. Damon |
In reply to this post by Blair McGlashan
Blair,
> At Smalltalk Solutions 2001 (I think) there was a panel on future > directions for Smalltalk (again, I think), at which Andy gave his > "Sea of Live Objects" speech, My pond metaphor is a kind of compromise between Andy's "sea" and my own internal picture which actually looks much more like a fish-tank ;-) > We were trying to encourage people to build > on this as a strength, but we came away thinking that it had not been > that well received. Since you also said: >[...] couldn't concieve of not having workspace variables, and I for > one found it very difficult to work in a famouse Smalltalk that > didn't have them at the time it's possible that these are connected and that, in fact, they really didn't "get it". > Personally I think the opposite is true. Programming in the debugger > is so powerful because [snipped] It must be partly a matter of taste. I very rarely PitD -- I find that it makes everything too concrete too soon. I tend, even in Smalltalk, to write reams of code, rewriting all the time as I discover new things about it, and don't usually execute much of it until it has settled down and stabilised a bit. I find that *executing* code is, frankly, just a distraction -- I just end up fixing errors in, or completing unfinished bits of, methods that will be completely re-written in a few minutes anyway. I work the same way in Java/C++/C, only on a *much* longer timescale. My record was going away and Just Programming for two/three weeks without going near a compiler. Came back, spent a couple of days just getting the code to compile, then the rest of the week getting it to work. It's not a way of working that I'd recommend to everyone ;-) but it suits me. In Smalltalk the timescale is minutes and hours, rather than days and weeks, but the idea's the same. You'll notice, though, that we agree about PitD putting you close to the objects as you code. It's just that you like it and I don't, usually. Just about the only times when I do PitD is when I've got a completely clear idea of what the code is going to look like before I start. In that case I find that going via the debugger helps to relieve the sheer tedium of cranking it all out. On that note, do you find that its a bit of a pain to select the "MNU" frame and then select "implement in=>" from the menu for each new method ? There's a nice keystroke combination to save the method and continue to the next one, CONTROL+{S, F5}, it would be nice if, say, CONTROL+1 meant "implement in receiver's class", CONTROL+2 meant "implement in receiver's superclass", etc, in which case the normal rhythm would be: [write the method body. CONTROL+{S, F5, 1}] repeat. But that's just a throwaway suggestion. -- chris |
In reply to this post by Damon
Damon,
> x := String new 'Hello world!'. > > String is a (class) object that lives in the image. The String object > can be identified by name: it is called 'String'. The variable x, > however, is not an object; it merely points to an (instance) object > that was just created. That newly created String instance now lives > in the image, but its identity is not explicit, as in the case of > 'String'. Its identity is hidden; only the variable 'x' knows the > identity of the instance. If x gets overwritten > > x := 5 > > that "Hello world!" instance loses its liveness, and is available for > garbage collection. So is it right to say that both instance and > class objects live in the image, but class objects are: > > 1) identified by explicit names > 2) already alive when introduced into the image > 3) and stay in the image indefinitely > 4) but do not have state information You are very much on the right lines, but there are a few corrections. In fact there's even *less* magic going on in Smalltalk than you might be thinking... The class String is an (long-lived) object, as you understand. It does indeed have a name, but try opening it in an inspector, and you'll see that its name is just part of its state. Classes have state too, as much as the programmer cares to give them, that's what the 'classInstanceVariableNames' are in the class definition. For instance ExternalLibrary has a class instvar called 'default', so the all class objects for classes derived from ExternalLibrary each have their own "field" which holds some of the state that is specific to that class. The connection between names of classes and the class objects themselves is made by the compiler looking them up in a global dictionary object. So if you have a reference to that dictionary (which I'll get to in a minute) then you can inspect it, or you can send it #at: messages (it's keyed by Symbol names), or you can loop over it's contents with #do: or #keysAndValuesDo:. That dictionary is not limited to holding classes, it can hold anything that's convenient. In practise it mainly does hold classes, in my image today it has 1402 entries, of which all but 46 a class objects. One exception is the object known as 'Transcript', so when you type something like: Transcript display: 'Hi there!'; cr. the Smalltalk compiler is looking up the name #Transcript in the global dictionary and generating code that sends the #display: and #cr messages to that object. You'll probably have realised that that amounts to having global variables in Smalltalk, and I'm sure that you've learned to shun them. Yet Smalltalk, supposedly one of the purest programming languages, makes *heavy* use of them! Every time you refer to a class you are actually reading the value of a global variable... The dictionary itself is known as 'Smalltalk' (i.e. one of the entries in the dictionary points back to itself). So you can play with it in a Workspace: Smalltalk size. or inspect it, if you are interested. BTW, just as not everything that has an entry in the Smalltalk dictionary is a class, not all classes have to have entries in the Smalltalk dictionary. So it's perfectly possible to have class objects that, as you put it, "have hidden identities". In point of fact, there is a "hidden" class object for every named class object in the system; the reasons are to do with the mechanics of Smalltalk classes, and I'd rather not get into that just now. Also it can sometimes be convenient to create anonymous classes for one reason or another. That's rather an advanced technique for most purposes, but -- for example (and a bit of entirely gratuitous self-advertisement) I create anonymous classes on the fly in my 'JNIPort' software (www.metagnostic.org) when I create Smalltalk objects that are proxies for Java objects. You said that you are interested in the meta-programming aspects of Smalltalk, you may not yet have realised that the "class definition" that you see in the class browser is a Smalltalk expression that sends a message to a class. If you step through that expression in the debugger then you can watch the details of how a new class is created or an existing class is modified. > To take things a little further do blocks live in the image? Yup! Inspect one. E.g. type: [:each | each thingumajig ]. in a workspace and then to an 'Inspect It', or browse its class (BlockClosure). > Finally constants (1,2,3,...) and literals ('hello world!') are: There's a subtlety about integers, so they are a bit of an exception, but in general what is happening is that when the compiler sees a literal expression, *it* creates a new object (a new String, say) and embeds a reference to that object into the compiled code that it generates. (Each method is compiled into an object -- naturally -- and part of the state of the method object is what's known as its "literal frame". When the compiler creates objects from the literal expressions, it adds them to the literal frame). Incidentally you can create arbitrary 'literals' by using the ##(...) syntax. It's not a thing to overuse, but if you write say: x := ##(MyComplicatedClass new). as part of a method, then the compiler will execute the code in brackets, and embed a reference to the resulting object in the compiled method. Actually it doesn't always create a new object, some literal expressions evaluate to "well-known" objects (like true and false) so the compiler just embeds a reference to that object in the method. Also it attempts to reuse String literals. That's why you should never try to modify an object that was generated from a literal. I said that integers are a bit of an exception, the reason is that -- for efficiencies sake -- the virtual machine uses a different representation for integers that will fit in 30 bits. They are still perfectly valid objects (you can send them messages, etc), but the representation is such that they are not allocated and garbage collected like other objects. > Perhaps this is much ado about nothing, but I was wondering whether > the workspace should be an object in the image, and if the state of > the workspace can be maintained as well. If so, then the workspace > has the added complexity that its state does not correspond to the > sequential layout of code it contains, as the order of evaluation of > its code is non-deterministic. That's exactly correct. The workspace is an object, and its state depends on the history of statements evaluated in it, not on the text that is displayed. E.g. you could "populate" a workspace with hundreds of objects, then delete all the text, but the objects would still be there. If you save and restore the image then the objects will still be there because they are part of its state. (That's different from saving the text of the workspace to a .ST file -- in that case all you are saving is the text). > 1) I assume it's possible to start off with an empty image, and > proceed from there by importing packages of code into the image to > work with objects. Well, in principle, yes. However if there are no objects in the image then there's nothing there that you can "tell" to import the package. There's no compiler object, there are none of the objects that constitute the IDE, so it's a little tricky to bootstrap the image. But you could start with a nearly empty image and do that; I *assume* that that's what Object-Arts do when they prepare a major new release. > Ie. Suppose I have only only 1 object called Main in the image with a > single method called doit. Can someone show me how to write the > Smalltalk code in the doit method to import a package and load a > String object into the image in order to create a 'Hello world' > string? I'm not sure what you are getting at here, are you asking how we create standalone applications with Dolphin ? If so, then we don't do it by populating a (nearly) empty image. It would be possible, and technically I'd prefer it if we did, but in fact Dolphin creates applications exactly the other way around. What happens (this requires the 'Pro' version of Dolphin) is that the system creates a new image by *removing* everything it can find that is provably superfluous. The process is known as 'stripping', and is the traditional way that Smalltalk applications are created. (If you are using D5 then it can also create a 'ToGo' executable, which is a single .exe file that has both the Smalltalk runtime and the resulting stripped image bundled into one file). > Ie, does one first use the workspace as a playground, and then > solidify the process by saving the code for the interactions into a > method by cutting and pasting the text from the workspace into the > CHB? For me its a bit of a mix. The vast bulk of my code is created directly as methods, but sometimes I want to try things out for a bit first. When I'm coding I'll quite often open a new workspace, try out a couple of expressions, then delete the workspace. I very rarely write code in a workspace that ends up being converted into a method. If my code is manipulating objects that I don't already know intimately then I'll do quite a lot of investigation in workspaces. If I'm only working with my own classes, then I hardly do it at all. I think there's probably quite a lot of difference between individual programmers on this point. > 3) Finally, I hear a great deal about how powerful a refactoring > browser is. What is a refactoring browser? I'd like to try one, but > the version of sample Dolphin Smalltalk in the Bracht book does not > contain a refactoring browser. In simple terms, tough, what does a > refactoring browser do? Refactors ;-) I'll leave it to someone else to give a non-facetious answer to that one. I don't use it myself and I don't think I'd do it justice. -- chris |
"Chris Uppal" <[hidden email]> wrote in message
news:3e847495$0$59861$[hidden email]... > > 3) Finally, I hear a great deal about how powerful a refactoring > > browser is. What is a refactoring browser? I'd like to try one, but > > the version of sample Dolphin Smalltalk in the Bracht book does not > > contain a refactoring browser. In simple terms, tough, what does a > > refactoring browser do? > > Refactors ;-) > > I'll leave it to someone else to give a non-facetious answer to that one. I > don't use it myself and I don't think I'd do it justice. I use these refactorings a lot: Extract Method. Hmm...this snippet belongs in its own method. Highlight it, press ^M, give it a name, and you're done. This is a biggie! Rename Method/Class/Variable. I use these almost without thinking now. Extract to Temporary. Takes a snippet and assigns it to a temporary. |
In reply to this post by Chris Uppal-3
Chris Uppal wrote:
> I made the Great Leap Forward from Java to (Dolphin) Smalltalk... Chris - I'm tutoring Smalltalk at Monash University this semester, and I've just put your post on the weblog I keep for my students. I'm hoping that some of them might read it and have that 'aha!' experience. Hope you don't mind your posts finding their way there - I can always remove it if you're not comfortable with that. Steve |
Steve Taylor wrote:
> > I made the Great Leap Forward from Java to (Dolphin) Smalltalk... > > Chris - I'm tutoring Smalltalk at Monash University this semester, and > I've just put your post on the weblog I keep for my students. I'm > hoping that some of them might read it and have that 'aha!' > experience. Hope you don't mind your posts finding their way there - Not in the least! My thanks to you, and to all the other who have said nice things about my post. -- chris |
In reply to this post by Chris Uppal-3
Chris,
I must thank you once again, for taking the time and effort to answer these newbie questions. I've learned a lot more about Smalltalk in these few exchanges than pouring through a few introductory books and notes I've assembled. This has really gotten my excited about becoming more proficient in the language and environment now that I can start seeing its possibilities and capabilities. A final question for everyone: Where can I find additinoal information on Smalltalk meta-programming Is a there a good reference on Smalltalk internals, and doing things like modifying its Parser and runtime environment? Mamy thanks for entertaining why questions. Damon. |
In reply to this post by Bill Schwab-2
"Bill Schwab" <[hidden email]> wrote in message news:<b6015m$ek88$[hidden email]>...
> Damon, > > > point: Is the workspace part of the image as well, so that saving the > > image saves the contents of the worksapce? > > Yes, though you might also want to periodically save the text to a separate > .st file; that way, you can reload the text if you close the workspace in > the image, or otherwise have an image meltdown. In that case, the separate > file is merely a backup (not unlike a package for classes, view resources, > etc.); your edits would affect only the copy in the image until you save the > file. For example, if you change the text, save the image but NOT the file, > then the image will reload with the changes to the text in the workspace, > but the file will not contain them. Please ask questions if that's not > clear. Thanks Bill, I think I got it. After Chris explained how the difference between a live object in the image and static code in a file or package, issues like this just fell into place. > > > > If so, is the workspace an > > object > > _Everything_ is an object :) The answer to your question is yes. > > > > (a singleton object) in the image? > > However, it is not a singleton, but that's either what you want, or if it is > a "problem" for you, there is a way to compensate for it. For some reason, I thought that there was only one workspace for the entire Smalltalk environment. This is clearly not the case as I can create multiple workspaces upon starting up the Smalltalk environment. It's great though, that Smalltalk provides facilities in which to one can modify its runtime-environment, including the Workspace. Damon |
In reply to this post by Damon
I see others have answered this question, but there are many different
answers. Like mine :-). Damon wrote: > > One proceeds by trying things out and experimenting in the workspace > to see if a program can be put together from a bunch of object > interactions. After a while if things start to work, to move the code > from the workspace and into a method? > I think some people work this way. I'm not one of them (usually). However, if I want to use a new object that I'm not familiar with, I'll play with it in a workspace for a while. But usually, I'll do as I describe below. > Ie, does one first use the workspace as a playground, and then > solidify the process by saving the code for the interactions into a > method by cutting and pasting the text from the workspace into the > CHB? > I generally practice what is called "Test-Driven Development" (there's a book by Kent Beck called "Test Driven Development By Example" that describes it better than I could in a short post). Using SUnit (ask about it if you're not familiar with it), I write a test for the next bit of functionality that I need to implement. I run it, and it fails. Then, I write the code to make it pass (this is where programming in the debugger works very well, although I don't do it as much as I could - I'm not used to the idea yet). After making the test pass in the simplest, fastest way possible, I refactor to clean up the mess I just made. Kent's book talks about a type of test called a "Learning Test" - a test that you write to help you learn how to use a particular object that you're not familiar with. I use these sometimes (though not as much as I could). In Smalltalk, it is often faster to use a workspace for this, although then the results of your learning doesn't stay in the code as it would with a test. > 3) Finally, I hear a great deal about how powerful a refactoring > browser is. What is a refactoring browser? I'd like to try one, but > the version of sample Dolphin Smalltalk in the Bracht book does not > contain a refactoring browser. In simple terms, tough, what does a > refactoring browser do? > I'm going to take the easy way out and refer you to another book, by Martin Fowler this time: "Refactoring: Improving the Design of Existing Code". Basically, a refactoring is a transformation of code that preserves its behavior. A refactoring browser can perform many such transformations automatically (and safely). Randy -- Randy Coulman NOTE: Reply-to: address is spam-guarded. Reassemble the following to reply directly: rvcoulman at acm dot org |
"Randy Coulman" <[hidden email]> wrote in message
news:b6be6g$3f4tc$[hidden email]... > I see others have answered this question, but there are many different > answers. Like mine :-). FWIW, my own approach is quite similar to yours. I learned about XP and TDD years ago (from my first edition of XP Explained), but now that I'm using Smalltalk, I feel like I'm finally where I belong. > Using SUnit (ask about it if you're not familiar with it), I write a > test for the next bit of functionality that I need to implement. I run > it, and it fails. This is standard TDD, but the added Smalltalk twist is that it doesn't necessarily have to fail the first time you run it. You can actually fix the test (i.e., add the functionality) while you're in the middle of it. What's even cooler is that you can fix the test _after_ it's failed (because the debugger can unwind the stack frame back to the changed method). > Then, I write the code to make it pass (this is where > programming in the debugger works very well, although I don't do it as > much as I could - I'm not used to the idea yet). I think this is where Chris's views have the most application to the way I work--the fact that I don't have to do the edit-compile-debug dance--I can just jump in the water, fight off the sharks, and emerge balancing the brightly-coloured ball on the end of my nose. Or something like that. >After making the test > pass in the simplest, fastest way possible, I refactor to clean up the > mess I just made. After programming this way in C++ for three years, I absolutely cannot believe how easy it is to do in Dolphin Smalltalk with the Refactoring Browser. |
Free forum by Nabble | Edit this page |