Mathieu Suen wrote:
> On Sep 5, 2007, at 2:45 AM, Peter William Lount wrote: > >> I wonder Alan, if you could, expand on what you mean by "but it needs >> to be done at the same level as regular programming (so it can be >> used by any base version of the language)"? > > I thinks he mean: don't add syntactic rules when you are using your > language. > > Mth > > > > Yes, that's the point I'm making as well in this thread of emails and articles on http://www.smalltalk.org: "Don't add syntactic rules when you are using your language unless there is no other alternative or unless it provides a compelling advantage." A special category of exceptions to library only extensions exist that enable the opening of a new dimension of capability. For example, blocks enable anyone to create new control flow structures in Smalltalk. It's still surprising how people are continuously innovating in with methods for blocks and unique ways of using them. I look for opportunities to enhance a language syntax that create these new dimensions. I see the gap of possibilities and a few innovative ways of using it but it's how big the gap is that's key. The curly braces don't create a new dimension of possibility beyond the few uses since the the curly braces are not extensible in the class libraries. However, the block version of continuously collecting statement evaluations does enable a new dimension. I don't know all the uses. But already in this discussion someone found one, by adding a third evaluator for concurrency purposes. That's not just another use but an entire other dimension found! Now to implement them and extend the power of blocks into the future. Other languages are catching up and surpassing Smalltalk - we need to keep up and jet to the future. Peter |
In reply to this post by Mathieu SUEN
At 06:08 PM 9/4/2007, Mathieu Suen wrote:
>I thinks he mean: don't add syntactic rules when you are using your >language. No, I didn't mean that. Right now in Smalltalk-80 one can choose a variety of syntax patterns (from a fixed set) when one defines a method. In Smalltalk-76, Dan Ingalls allowed more patterns (including prefixing, call by name, and the overloading of <- for setters and getters, etc.). This was nicer IMO. In Smalltalk-72 you could actually define the input grammar when writing a method. This was even better IMO (even though we perhaps went too far). One variation that lies between the ST-80/ST-76 and the unrestricted grammars of ST-72 (and earlier: Irons' IMP language) that we've talked about over the years but never done to Smalltalk-80 is to make up an interface language (that is, a grammar for making grammatical extensions which allows more forms to be defined but curbs thoughtless anarchies). Also/or, the ST-72 approach could be easily fixed and made into something that would not produce any ambiguities at run time....and would allow full compilation. Each of these would probably most naturally be handled by modifying what can be said in the heading of a method. In any case, what I meant was that it is too opaque to redefine a pragmatically written compiler etc., for making most graceful extensions. This is generally what is required for Smalltalk-80 and leads away from a base language that is extended to an explosion of different languages. So I meant that all extensions to the base language should be simply visible as part of the new code that is added by the extender and not be hidden in low level mechanisms if at all possible. But there are many ways to do graceful useful extensions without redefining the base language. ST-80 would have to be fixed a little to allow this, but this kind of deeper extension would pay real dividends in many areas. At a deeper level, why not just make a better language than ST-80? But partly do this by making a better meta-system so that the simple needs for new forms and behaviors don't have to spark so much reverberating discussion in the year 2007. While at this, I think I'd also be tempted to try to make a more fruitful architecture than ST-80 supplies for dealing with semantic variants (cf the long discussions about problems of packages, Monticello, etc.). The problems come from lacks of architectural semantics for dealing with this kind of modularity and I don't think trying to supply "life support" in the form of external tools is going to help much in the long run. This is an important problem that no language and DE handles well, and it's worthwhile trying to figure out a stronger semantics to deal with it. Cheers, Alan At 06:08 PM 9/4/2007, Mathieu Suen wrote: >On Sep 5, 2007, at 2:45 AM, Peter William Lount wrote: > >>I wonder Alan, if you could, expand on what you mean by "but it >>needs to be done at the same level as regular programming (so it >>can be used by any base version of the language)"? > >I thinks he mean: don't add syntactic rules when you are using your >language. > > Mth > > |
In reply to this post by Andreas.Raab
Andreas Raab wrote:
> Peter William Lount wrote: >> I wonder Alan, if you could, expand on what you mean by "but it needs >> to be done at the same level as regular programming (so it can be >> used by any base version of the language)"? > > Isn't that obvious? Hi Andreas, It might be. I was asking Alan to hear it from him though. Different people have different perspectives which I value. They are also not always what I expect; that's the value of a question and an interested listener. Cheers, Peter |
In reply to this post by Randal L. Schwartz
Randal L. Schwartz wrote:
>>>>>> "David" == David T Lewis <[hidden email]> writes: >>>>>> > > David> On Tue, Sep 04, 2007 at 11:27:43AM -0400, Jon Hylands wrote: > >>> ps - since I just turned 40 a couple days ago, that means I've been using >>> Smalltalk for half my life - pretty cool :-) >>> > > David> Dang. I'll be at least 90 before I can say that. > > I was able to say that about 5 years ago. :) > > Not that I was 90, but that I was twice as old as I was when I first compiled > a method. :-) > > I think it was 1982 when I first got my hands on a Magnolia at Tek, executing > the ST80 image. If that was 1983, then that would have been only three years > ago. I *know* I was executing that before leaving for ServioLogic (later > Gemstone) in 84, so that's pretty much a done deal by now, one way or the > other. > > Wow. Smalltalkers have grown up, that's for sure. It was 1979 that I saw the Scientific American article on Smalltalk and 1980 when I read the Byte August issue on Smalltalk. In 1984 I got my hands on a copy of Smalltalk for the Macintosh plus for USD$50.00 from Apple. It was cool but only had 50K free on the 1MB machine! How times change! Also, in 1982 I started the video game Gemstone Warrior that uses a limited from of objects in it's simulation - all things were objects from the user interface perspective - in Apple ][ assembly language no less. Not Rosettastone Smalltalk for the Apple ][ but objects non-the-less. For me it's been over half my life so far with 23 years of hands on and almost half my life with 28 years of knowing about Smalltalk's object notions and building software without any hands on. Cheers, peter |
In reply to this post by Andreas.Raab
Yep --
There are lots of ways to do this. One way that is like the fixed patterns of ST-80, but has more patterns, is the extreme operator grammar technique used by Joe Goguen for OBJ. This has all the operator possibilities: infix, outfix, prefix, postfix, etc. Another way would be to allow implicit self in ST-80. This would allow control syntaxes that are usually prefixed (like if...then...else, for, while, etc) to be simple methods of a high level class (like class object). As Bert pointed out a few days ago, the semantics of a class in ST-80 is local to the class (each class can have its own compiler). One could alternately choose to have this be true at the method level. One could have real method classes whose instances own some of the polymorphic intent of the method (and also the syntax, including special syntax that might make the method more clear). Cheers, Alan At 07:02 PM 9/4/2007, Andreas Raab wrote: >Peter William Lount wrote: >>I wonder Alan, if you could, expand on what you mean by "but it >>needs to be done at the same level as regular programming (so it >>can be used by any base version of the language)"? > >Isn't that obvious? When you add the method #frobler to Object you >extend the language. And at the same level as regular programming. >For example, one could consider implementing operators that way, say >in a Prolog style, priority driven way: > >Object>>plus: anObject > <operator: #+ type: #yfx priority: 500> > >Object>>minus: anObject > <operator: #- type: #yfx priority: 500> > >This implements all the semantics as plain messages but leaves >operators as syntactic sugar on top of them. The compiler would >translate "a + b" into "a plus: b" and the decompiler -if it knows >about the plus operator in your system- would decompile as #+. If it >didn't know about it, it would decompile as #plus:. Your code would >depend on the "PlusMinus" package that other people have to load >(since it contains the operator definitions). Etc. It's pretty straightforward. > >Cheers, > - Andreas |
In reply to this post by pwl
On 9/5/07, Peter William Lount <[hidden email]> wrote:
> > You are still stuck on byte codes eh? That is so 1960's. I invite you > into the innovation frame of mind, discard what you think you know about > this topic, and open your eyes wide open and imagine a future with > powerful blocks. We are just scratching the surface with this one new > block feature. I've invented ten more powerful capabilities for blocks > and integrated them so they work well. > > There are many ways to implement the two evaluators for blocks. For > example, depending on your byte code set you could have a bit for a > flag, or you could duplicate the byte codes with one set for each > evaluation type. Or you could get rid of byte codes all together which > is the better approach. What Smalltalk system doesn't use byte codes? As far as the blocks question, I think it's not a bad idea. The idea of a block is already overloaded somewhat with: [ "..." ] fork |
In reply to this post by Alan Kay
On 9/5/07, Alan Kay <[hidden email]> wrote:
> > Another way would be to allow implicit self in ST-80. This would > allow control syntaxes that are usually prefixed (like > if...then...else, for, while, etc) to be simple methods of a high > level class (like class object). I don't think the "implicit self" concept has been very successful in practice. Last I heard, in C++ the best practices were to always explicitly call this. Though in C++ it's ambiguous whether you are calling a method or a free standing function. In Java this ambiguity would not exist, but you are required to spell out this (not that Java is the pinnacle of language design, but much of their design is reaction to problems with C++). I have seen you mention at least one other time that we should simply use/make a better language then ST-80. Do you have any syntax examples of what you have in mind? I have always been curious as to your thinking here, as for myself I think Smalltalk is very near perfection. It does need a powerful way of packaging (perhaps what VW has is the way to go?), multi-methods like Lisp has would be good if one could figure out a syntactical way of specifying that and I think adding macros to the standard could be nice as well. But beyond that I really can't think of anything I would change syntax-wise. |
In reply to this post by pwl
On 9/5/07, Peter William Lount <[hidden email]> wrote:
> > The key is in how it's evaluated. With a block that can be chosen at run > time whereas with the curly braces it's much more limited since they > just syntax sugar and don't have the power of the capabilities of the block. Well, you have more power because it's at runtime instead of compile time, but it's also slower if there are no compiler hooks. Personally what I would like is if Smalltalk did what Lisp did and pronounce # as the place where extensions happen. Like instead of braces it would be #{}. Then folks from other dialects would immediately know that an extension is happening and where to look for it. |
In reply to this post by Jason Johnson-5
Jason Johnson wrote:
> On 9/5/07, Peter William Lount <[hidden email]> wrote: > >> You are still stuck on byte codes eh? That is so 1960's. I invite you >> into the innovation frame of mind, discard what you think you know about >> this topic, and open your eyes wide open and imagine a future with >> powerful blocks. We are just scratching the surface with this one new >> block feature. I've invented ten more powerful capabilities for blocks >> and integrated them so they work well. >> >> There are many ways to implement the two evaluators for blocks. For >> example, depending on your byte code set you could have a bit for a >> flag, or you could duplicate the byte codes with one set for each >> evaluation type. Or you could get rid of byte codes all together which >> is the better approach. >> > > What Smalltalk system doesn't use byte codes? > > As far as the blocks question, I think it's not a bad idea. The idea > of a block is already overloaded somewhat with: > > [ "..." ] fork > > > Hmmm.... that's actually a good question... a number of them use native code but may actually use byte codes as an intermediate step... Byte codes are fine but they loose information that advanced compilation techniques really need. I believe that there are papers out there on this... can't remember the titles at the moment... Byte codes is just one way to implement the world. The version of Smalltalk that I'm working, on, known as ZokuTalk(tm) won't use byte codes at all anywhere. It goes from the parse tree structure to another set of internal representations (which don't look like byte codes) and then to native machine code... that's the design anyway. There are no saved byte codes. At this time I'm working on the compiler. ZokuTalk is a layer upon the ZokuScript(tm) language. The intention of ZokuTalk is to be highly compatible with the Smalltalk code base and language syntax. ZokuTalk translates into ZokuScript and then to native code through a number of internal layers none of which are byte codes. ZokuScript is a decedent of Smalltalk, Lisp and a group of other languages and takes Smalltalk and object languages to a whole new level. Blocks feature prominently in ZokuScript as does a whole new meta facility. In fact there are about ten or fifteen new dimensions of capability that I've been able to integrate into Blocks. Messages are also fully first class objects for the first time in any language. Remember Alan Kay said: "Smalltalk is object-oriented, but it should have been message oriented" and "The big idea is 'messaging'". Those are key thoughts for a meta system. The breakthrough achieved in the ZokuScript syntax is the integration of meta syntax using fully recognizable Smalltalk style syntax and message sending itself to implement and access all aspects of the entire system, even components inside the virtual machine (if you want to call it that). No additional syntax characters were needed! So I gather that there is at least one version of Smalltalk that doesn't use byte codes. The Self language takes things the other extreme and minimizes the set of byte codes to seven core codes. Then methods are compiled to native code on the fly, and with multiple compiled versions based upon the actual parameter objects that are passed into the methods. So a method might have a version optimized for integer parameters and another for floating point or yet another for fractions; plus a general purpose version. There is no need really for Self to have byte codes at all other than as a compact representation. Also the Audition Smalltalk clone that the now defunct Synaptec Corporation of Vancouver, BC was working on for the National Research Council of Canada wasn't based upon byte codes but upon a Forth like virtual machine with an unlimited extensible set of primitive operations that implemented and allowed for low level extensions (and for variations in the input syntax of methods). Oh, this is one project that makes me shy of various input syntaxes for methods, since it just makes life confusing. Having one potent yet simple and beautify language that can handle a huge variety of problem representations is valuable. Smalltalk can represent a lot, however, with some judicious extensions it can handle much larger set of inputs. Merging of Blocks and Methods in ZokuScript and Also Potentially for Smalltalk For example, blocks and methods at the source code level are 95% the same. In ZokuScript they become the same and completely interchangeable. Sure at run time the system needs to implement them differently. This enables the elimination of the Smalltalk legacy chunk format for source code that serves little purpose anymore. It also makes supporting other object models trivial at the source code level. Here is an example of a "method" being defined as a "block" and stored as a method on a class, Person. Note how the block includes a name, thus the block is a keyword named block. [ Object subClass: #Person. aBlock := [firstName: firstNameString lastName: lastNameString | firstName := firstNameString. lastName := lastNameString ]. Person addInstanceMethod: aBlock. "..." "..." "..." ] fileIn. Part of the point of merged blocks and method source syntax is the elimination of a cryptic syntax, the source code chunk format; another point is the options it opens for alternative object models; another and very important benefit is that the source code falls into one uniform syntax with the maximum expressive power from each element of the syntax; this results in a language integration that is flexible and powerful. At least that's the goal. The above integration of block and method syntax would also work for Smalltalk quite wonderfully. That is why I share it with the group. I've shared it with others before but it's time to let the wider world know about it. I hope that you see the benefits and think it valuable enough to add to your Smalltalk system. Welcome to one of the futures of Smalltalk, ZokuScript. Cheers, Peter ZokuTalk and ZokuScript are trademarks of Active Information Corporation. |
In reply to this post by Andreas.Raab
Hi Andreas,
on Wed, 05 Sep 2007 00:55:21 +0200, you wrote: > Damien Pollet wrote: >> (*) just on this point I'd prefer to write something like >> {[a]. [:x| x b]. [:x | x c]} valueAsChain > > Nah. I want to write: > > [a. b. c] piped. With Marcus' Reflectivity.image that'd be easy to achieve, there you can inspect doSomething | a b c | "self doSomething" ^ [a. b. c] home method reflectiveMethod blocks first body statements From such an expression it's only a small step to tell the compiler what you want from the block-of course *not*limited* by some dogmatic ;; syntax extension ;-) but powered by everything that Smalltalk permits :) Marcus has shown some expressive examples what his reflectivity can do post-compile time as well as at-compile time in his ESUG 2007 presentation. > SCNR, > - Andreas SCNR, either :) /Klaus |
In reply to this post by pwl
On 05/09/07, Peter William Lount <[hidden email]> wrote:
> You are still stuck on byte codes eh? That is so 1960's. I invite you > into the innovation frame of mind, discard what you think you know about > this topic, and open your eyes wide open and imagine a future with > powerful blocks. We are just scratching the surface with this one new > block feature. I've invented ten more powerful capabilities for blocks > and integrated them so they work well. That's for another thread. I'm not against crazy ideas on blocks, I just say that to implement message chains, it's a smaller and easier to understand change to make the compiler expand some new syntactic sugar. Overloading the meaning of blocks really feels more disruptive to me, especially if it involves potentially calling the compiler or reflectivity at each evaluation. I like the idea to use # for extending an otherwise unmodified syntax. > It's important that a system be as dynamic as possible. You may need to > recompile the block at runtime just before it's evaluated if you insist > on remaining with the out molded notion of byte codes. But there are > other ways. One could simply add a byte code marker for statements as > the "add to collection byte code" above illustrated. There are many > other ways if you are creative and innovative. You would need to add markers for each possible evaluation strategy, and if the system is extensible you can't know which strategy will exist in advance. The way to deal with that is to keep the current blocks as they are, sequential statements that will be executed efficiently, and add a new kind of code container that has the clear meaning of an set of statements that can be executed by different strategies. These new code container objects are higher-level than blocks. In fact you already have them: { [a]. [b]. [c] } valuesConcurrently now we can imagine a nicer syntax than that, but besides conflicting with current blocks, [a.b.c] would make it difficult to have complex statements in place of a b or c. Another nice solution would be to add a compiler hint to blocks: [a. b. c <concurrent>] value Here, this block would be recognized at compile-time to have special semantics and the compiler would generate parallel code. That would be really useful for numerical stuff like aBigArray simdDo: [:each| a. b. c] which would evaluate first a for each element, then b, then c (three simd-optimized loops instead of a single big loop) -- Damien Pollet type less, do more [ | ] http://typo.cdlm.fasmz.org |
In reply to this post by Jason Johnson-5
On Tue, 04 Sep 2007 21:35:43 -0700, Jason Johnson
<[hidden email]> wrote: > I don't think the "implicit self" concept has been very successful in > practice. Last I heard, in C++ the best practices were to always > explicitly call this. One rarely sees "Self" in Delphi. The constant references to "self" is one of the clunkier things about Smalltalk, in my view, and is inconsistent to boot (you have to use self to access methods but not fields?). > It does need a powerful way of packaging (perhaps what VW has is the > way to go?), multi-methods like Lisp has would be good if one could > figure out a syntactical way of specifying that and I think adding > macros to the standard could be nice as well. But beyond that I > really can't think of anything I would change syntax-wise. I've always felt macros tended to obscure things, but then I've only used them in things like the C-family and PL/I. |
In reply to this post by Alan Kay
On Tue, 04 Sep 2007 19:39:17 -0700, Alan Kay <[hidden email]>
wrote: > In any case, what I meant was that it is too opaque to redefine a > pragmatically written compiler etc., for making most graceful > extensions. This is generally what is required for Smalltalk-80 and > leads away from a base language that is extended to an explosion of > different languages. So I meant that all extensions to the base language > should be simply visible as part of the new code that is added by the > extender and not be hidden in low level mechanisms if at all possible. The idea being that...particular tasks would have their own sort-of-dialect? > While at this, I think I'd also be tempted to try to make a more > fruitful architecture than ST-80 supplies for dealing with semantic > variants (cf the long discussions about problems of packages, > Monticello, etc.). The problems come from lacks of architectural > semantics for dealing with this kind of modularity and I don't think > trying to supply "life support" in the form of external tools is going > to help much in the long run. This is an important problem that no > language and DE handles well, and it's worthwhile trying to figure out a > stronger semantics to deal with it. I seem to recall Bertrand Meyer trying to do something like that with Eiffel. (I studied the heck out of Eiffel when Meyer first wrote his books and ended up waiting and waiting and waiting....) It seems like most gyrations done to existing languages to get them to support IDEs are severe and don't get them to the Etoys inspector level. |
In reply to this post by Andreas.Raab
Would be a nice evolution for smalltalk.
I always wanted to look at the way lisaac is doing infix and other notation (but it should not be that powerful). On 5 sept. 07, at 04:02, Andreas Raab wrote: > Peter William Lount wrote: >> I wonder Alan, if you could, expand on what you mean by "but it >> needs to be done at the same level as regular programming (so it >> can be used by any base version of the language)"? > > Isn't that obvious? When you add the method #frobler to Object you > extend the language. And at the same level as regular programming. > For example, one could consider implementing operators that way, > say in a Prolog style, priority driven way: > > Object>>plus: anObject > <operator: #+ type: #yfx priority: 500> > > Object>>minus: anObject > <operator: #- type: #yfx priority: 500> > > This implements all the semantics as plain messages but leaves > operators as syntactic sugar on top of them. The compiler would > translate "a + b" into "a plus: b" and the decompiler -if it knows > about the plus operator in your system- would decompile as #+. If > it didn't know about it, it would decompile as #plus:. Your code > would depend on the "PlusMinus" package that other people have to > load (since it contains the operator definitions). Etc. It's pretty > straightforward. > > Cheers, > - Andreas > > |
In reply to this post by Blake-5
On 5-Sep-07, at 1:24 AM, Blake wrote: > The constant references to "self" is one of the clunkier things > about Smalltalk, in my view, Gronk? What is clunky about a uniform, consistent syntax that has us a) name the recipient b) name the message to send to it c) name any parameters to include with the message Having a special case that lets you leave out the recipient if it is 'self' would be clunky, confusing and tasteless. > and is inconsistent to boot (you have to use self to access methods > but not fields?). You can of course use messages to access instvars. It wouldn't be terribly difficult to make the compiler require it. I think it would be going a bit far, personally - using accessor messages sounds nice until you remember that they expose information you might prefer to keep private. If anyone has a good solid idea for proper private methods I'd be very interested. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim "How many Grogs does it take to change a lightbulb?" "One. Something with manipulatory appendages will be along eventually." |
In reply to this post by Blake-5
On 9/5/07, Blake <[hidden email]> wrote:
> On Tue, 04 Sep 2007 21:35:43 -0700, Jason Johnson > <[hidden email]> wrote: > > One rarely sees "Self" in Delphi. The constant references to "self" is one > of the clunkier things about Smalltalk, in my view, and is inconsistent to > boot (you have to use self to access methods but not fields?). I don't find it clunky because the methods are so small. I don't find it inconsistent because variables are the only thing that are not messages, so if you don't see it in the method declaration it's an instance variable. But that's just me, this is all so much easier then C++ was. > I've always felt macros tended to obscure things, but then I've only used > them in things like the C-family and PL/I. No no no. I don't know PL/I but it's a joke to call what C has macros. That is just search and replace prepossessing nonsense. A lisp-style macro is the full power of the language at compile time. The only rule is, what ever the function produces has to be valid syntax because when the method is compiled, any macros are executed and their output is expanded at the call site. So, contrived example: MyClass>>generateTimestamp ^ stream contents: [:stream| stream nextPutAll: 'Method compiled by '; nextPutAll: MyClass current_author; nextPutAll: ' on the date of '; nextPutAll: DateAndTime now ] MyClass>>someRandomMethod Logger log: ##(MyClass generateTimestamp), ' entering someRandomMethod' Now, as I said, this is contrived, but the thing to notice here is that the string generated by #generateTimestamp is inserted *at compile time* and is therefor a constant with all the values fixed to what they were when the method was compiled. The main use of macros in Lisp is actually to implement new control structures because the other property of macros is that they don't force evaluation of their arguments (unless they want to). So they basically take the source code text as input and modify what actually gets compiled as C macros do, but the big difference is they have any function that was defined prior (built in or otherwise) available to help make the transformations. Speed of the functions don't matter so much because it's at compile time (and likely incrementally compiled). Having said all that, macros aren't the same enabler in Smalltalk that they are in Lisp, but one place that stands out to me as a place they can really help Smalltalk is situations like this about adding syntax. In Lisp the # is the place for putting custom extensions so people make reader macros for new # syntax. If we had something like this in Smalltalk then it would mean to do what {} does we wouldn't have to touch a compiler. Just define a reader macro (how ever that would be done) that does the text conversion of e.g. #{} to the smalltalk syntax equivalent of whatever {} is outputting now. |
On 05/09/07, Jason Johnson <[hidden email]> wrote:
> On 9/5/07, Blake <[hidden email]> wrote: > > On Tue, 04 Sep 2007 21:35:43 -0700, Jason Johnson > > <[hidden email]> wrote: > > > > One rarely sees "Self" in Delphi. The constant references to "self" is one > > of the clunkier things about Smalltalk, in my view, and is inconsistent to > > boot (you have to use self to access methods but not fields?). > > I don't find it clunky because the methods are so small. I don't find > it inconsistent because variables are the only thing that are not > messages, so if you don't see it in the method declaration it's an > instance variable. But that's just me, this is all so much easier > then C++ was. > > > I've always felt macros tended to obscure things, but then I've only used > > them in things like the C-family and PL/I. > > No no no. I don't know PL/I but it's a joke to call what C has > macros. That is just search and replace prepossessing nonsense. A > lisp-style macro is the full power of the language at compile time. > The only rule is, what ever the function produces has to be valid > syntax because when the method is compiled, any macros are executed > and their output is expanded at the call site. > > So, contrived example: > > MyClass>>generateTimestamp > ^ stream contents: [:stream| > stream > nextPutAll: 'Method compiled by '; > nextPutAll: MyClass current_author; > nextPutAll: ' on the date of '; > nextPutAll: DateAndTime now ] > > MyClass>>someRandomMethod > Logger log: ##(MyClass generateTimestamp), ' entering someRandomMethod' > > Now, as I said, this is contrived, but the thing to notice here is > that the string generated by #generateTimestamp is inserted *at > compile time* and is therefor a constant with all the values fixed to > what they were when the method was compiled. > > The main use of macros in Lisp is actually to implement new control > structures because the other property of macros is that they don't > force evaluation of their arguments (unless they want to). So they > basically take the source code text as input and modify what actually > gets compiled as C macros do, but the big difference is they have any > function that was defined prior (built in or otherwise) available to > help make the transformations. Speed of the functions don't matter so > much because it's at compile time (and likely incrementally compiled). > > Having said all that, macros aren't the same enabler in Smalltalk that > they are in Lisp, but one place that stands out to me as a place they > can really help Smalltalk is situations like this about adding syntax. > In Lisp the # is the place for putting custom extensions so people > make reader macros for new # syntax. If we had something like this in > Smalltalk then it would mean to do what {} does we wouldn't have to > touch a compiler. Just define a reader macro (how ever that would be > done) that does the text conversion of e.g. #{} to the smalltalk > syntax equivalent of whatever {} is outputting now. > > Currently it used only for generating primitives in method headers, but with subtle changes pragma can be used as a macro without introducing any new #... constructs. Then sample above can be written with pragma: MyClass>>someRandomMethod Logger log: <MyClass generateTimestamp> , ' entering someRandomMethod' -- Best regards, Igor Stasenko AKA sig. |
To be honest I think pragmas are starting to be overrated. I don't
even know where to look to see what happens when a pragma is seen. I suppose it is theoretically as powerful in this particular case as macros, but for me the macros feel much more consistent. I would see pragmas as useful for the kind of things that Lisp does with declare, i.e. telling the compiler the type of the argument so it can specialize the method, tell the compiler to generate for fast code, not safety, and so on. In other words, a kind of annotation, since that's what it looks like to me. On 9/5/07, Igor Stasenko <[hidden email]> wrote: > On 05/09/07, Jason Johnson <[hidden email]> wrote: > > On 9/5/07, Blake <[hidden email]> wrote: > > > On Tue, 04 Sep 2007 21:35:43 -0700, Jason Johnson > > > <[hidden email]> wrote: > > > > > > One rarely sees "Self" in Delphi. The constant references to "self" is one > > > of the clunkier things about Smalltalk, in my view, and is inconsistent to > > > boot (you have to use self to access methods but not fields?). > > > > I don't find it clunky because the methods are so small. I don't find > > it inconsistent because variables are the only thing that are not > > messages, so if you don't see it in the method declaration it's an > > instance variable. But that's just me, this is all so much easier > > then C++ was. > > > > > I've always felt macros tended to obscure things, but then I've only used > > > them in things like the C-family and PL/I. > > > > No no no. I don't know PL/I but it's a joke to call what C has > > macros. That is just search and replace prepossessing nonsense. A > > lisp-style macro is the full power of the language at compile time. > > The only rule is, what ever the function produces has to be valid > > syntax because when the method is compiled, any macros are executed > > and their output is expanded at the call site. > > > > So, contrived example: > > > > MyClass>>generateTimestamp > > ^ stream contents: [:stream| > > stream > > nextPutAll: 'Method compiled by '; > > nextPutAll: MyClass current_author; > > nextPutAll: ' on the date of '; > > nextPutAll: DateAndTime now ] > > > > MyClass>>someRandomMethod > > Logger log: ##(MyClass generateTimestamp), ' entering someRandomMethod' > > > > Now, as I said, this is contrived, but the thing to notice here is > > that the string generated by #generateTimestamp is inserted *at > > compile time* and is therefor a constant with all the values fixed to > > what they were when the method was compiled. > > > > The main use of macros in Lisp is actually to implement new control > > structures because the other property of macros is that they don't > > force evaluation of their arguments (unless they want to). So they > > basically take the source code text as input and modify what actually > > gets compiled as C macros do, but the big difference is they have any > > function that was defined prior (built in or otherwise) available to > > help make the transformations. Speed of the functions don't matter so > > much because it's at compile time (and likely incrementally compiled). > > > > Having said all that, macros aren't the same enabler in Smalltalk that > > they are in Lisp, but one place that stands out to me as a place they > > can really help Smalltalk is situations like this about adding syntax. > > In Lisp the # is the place for putting custom extensions so people > > make reader macros for new # syntax. If we had something like this in > > Smalltalk then it would mean to do what {} does we wouldn't have to > > touch a compiler. Just define a reader macro (how ever that would be > > done) that does the text conversion of e.g. #{} to the smalltalk > > syntax equivalent of whatever {} is outputting now. > > > > > Dont forget about pragma syntax in smalltalk. > Currently it used only for generating primitives in method headers, > but with subtle changes pragma can be used as a macro without > introducing any new #... constructs. > > Then sample above can be written with pragma: > > MyClass>>someRandomMethod > Logger log: <MyClass generateTimestamp> , ' entering someRandomMethod' > > -- > Best regards, > Igor Stasenko AKA sig. > > |
> To be honest I think pragmas are starting to be overrated. I don't
> even know where to look to see what happens when a pragma is seen. I > suppose it is theoretically as powerful in this particular case as > macros, but for me the macros feel much more consistent. What about looking for senders and implementors of the pragma selector? > I would see pragmas as useful for the kind of things that Lisp does > with declare, i.e. telling the compiler the type of the argument so it > can specialize the method, tell the compiler to generate for fast > code, not safety, and so on. In other words, a kind of annotation, > since that's what it looks like to me. Things like these have been done in Philippe Marschall's master thesis: http://www.iam.unibe.ch/~scg/cgi-bin/scgbib.cgi/abstract=yes?Mars06a Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
In reply to this post by Jason Johnson-5
Oh, my fault , i forgot that pragmas can be used as starting
exression, but not inside other valid smalltalk exression. On 05/09/07, Jason Johnson <[hidden email]> wrote: > To be honest I think pragmas are starting to be overrated. I don't > even know where to look to see what happens when a pragma is seen. I > suppose it is theoretically as powerful in this particular case as > macros, but for me the macros feel much more consistent. > > I would see pragmas as useful for the kind of things that Lisp does > with declare, i.e. telling the compiler the type of the argument so it > can specialize the method, tell the compiler to generate for fast > code, not safety, and so on. In other words, a kind of annotation, > since that's what it looks like to me. > > On 9/5/07, Igor Stasenko <[hidden email]> wrote: > > On 05/09/07, Jason Johnson <[hidden email]> wrote: > > > On 9/5/07, Blake <[hidden email]> wrote: > > > > On Tue, 04 Sep 2007 21:35:43 -0700, Jason Johnson > > > > <[hidden email]> wrote: > > > > > > > > One rarely sees "Self" in Delphi. The constant references to "self" is one > > > > of the clunkier things about Smalltalk, in my view, and is inconsistent to > > > > boot (you have to use self to access methods but not fields?). > > > > > > I don't find it clunky because the methods are so small. I don't find > > > it inconsistent because variables are the only thing that are not > > > messages, so if you don't see it in the method declaration it's an > > > instance variable. But that's just me, this is all so much easier > > > then C++ was. > > > > > > > I've always felt macros tended to obscure things, but then I've only used > > > > them in things like the C-family and PL/I. > > > > > > No no no. I don't know PL/I but it's a joke to call what C has > > > macros. That is just search and replace prepossessing nonsense. A > > > lisp-style macro is the full power of the language at compile time. > > > The only rule is, what ever the function produces has to be valid > > > syntax because when the method is compiled, any macros are executed > > > and their output is expanded at the call site. > > > > > > So, contrived example: > > > > > > MyClass>>generateTimestamp > > > ^ stream contents: [:stream| > > > stream > > > nextPutAll: 'Method compiled by '; > > > nextPutAll: MyClass current_author; > > > nextPutAll: ' on the date of '; > > > nextPutAll: DateAndTime now ] > > > > > > MyClass>>someRandomMethod > > > Logger log: ##(MyClass generateTimestamp), ' entering someRandomMethod' > > > > > > Now, as I said, this is contrived, but the thing to notice here is > > > that the string generated by #generateTimestamp is inserted *at > > > compile time* and is therefor a constant with all the values fixed to > > > what they were when the method was compiled. > > > > > > The main use of macros in Lisp is actually to implement new control > > > structures because the other property of macros is that they don't > > > force evaluation of their arguments (unless they want to). So they > > > basically take the source code text as input and modify what actually > > > gets compiled as C macros do, but the big difference is they have any > > > function that was defined prior (built in or otherwise) available to > > > help make the transformations. Speed of the functions don't matter so > > > much because it's at compile time (and likely incrementally compiled). > > > > > > Having said all that, macros aren't the same enabler in Smalltalk that > > > they are in Lisp, but one place that stands out to me as a place they > > > can really help Smalltalk is situations like this about adding syntax. > > > In Lisp the # is the place for putting custom extensions so people > > > make reader macros for new # syntax. If we had something like this in > > > Smalltalk then it would mean to do what {} does we wouldn't have to > > > touch a compiler. Just define a reader macro (how ever that would be > > > done) that does the text conversion of e.g. #{} to the smalltalk > > > syntax equivalent of whatever {} is outputting now. > > > > > > > > Dont forget about pragma syntax in smalltalk. > > Currently it used only for generating primitives in method headers, > > but with subtle changes pragma can be used as a macro without > > introducing any new #... constructs. > > > > Then sample above can be written with pragma: > > > > MyClass>>someRandomMethod > > Logger log: <MyClass generateTimestamp> , ' entering someRandomMethod' > > > > -- > > Best regards, > > Igor Stasenko AKA sig. > > > > > > -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |